perm filename HELIB.KKP[S,DOC]5 blob sn#026429 filedate 1973-02-28 generic text, type T, neo UTF8
                          HAND/EYE LIBRARY                        1-1


                      HAND/EYE LIBRARY (HELIB)

                           Karl K. Pingle



                            INTRODUCTION



        This is  an update  of SAILON  35.1.  In  order to  enter the
SAILON into the  computer, some formulae  and all diagrams  have been
taken  out of  the text  and appear  on seperate  pages which  may be
obtained from  me and  inserted into the  listing wherever  you want.
They are keyed to the text.
                          HAND/EYE LIBRARY                        1-2


                          TABLE OF CONTENTS
                          _____ __ ________

        General Information
        _______ ___________

        2-1     Introduction

        2-3     SAIL Calling Sequences

        2-5     I/O Initialization

        2-6     TV Camera

        2-9     Buffer and Variable Initialization

        2-10    GLOBAL - Global Variables (including status vector)

        Adjusting the TV Camera
        _________ ___ __ ______

        3-1     TSERVO - Pan, Tilt, and Focus Control (COHU CAMERA)

        3-7     EYECAL - TV Calibration Routine

        3-8     DACO - Set TV Target Voltage and read AD

        3-11    WHEEL - Color Wheel Manipulator

        3-12    TVPOT - Read TV motor pots during TV reading

        Inputting a TV Buffer
        _________ _ __ ______

        4-1     INP - Sets Area to be Read in

        4-2     TVIN - Read a TV Image

        4-4     PICRD - Input a TV Image from the disk

        Randomly Accessing the TV Image
        ________ _________ ___ __ _____

        5-1     ENTER - Buffer access and storing
                        (magnitude and gradient)

        5-4     ENT - Adjust limits of TV input

        Operate on the TV Image
        _______ __ ___ __ _____

        6-1     HISTO - Form a Histogram

        6-2     OPER - Hueckel's  edge Operator
                          HAND/EYE LIBRARY                        1-3


        6-6     AVERAG - Averaging Routine

        6-7     DIFR - Differencing images and processing them

        6-9     DISP - Display a differenced image

        6-10    OP - Hueckel's new edge-line operator

        TV Buffer Output
        __ ______ ______

        7-1     PICWR - Output to the disk

        7-3     PICSPL - Spool images for the line printer

        7-4     PORTR - Adjust image aspect ratio for line printer

        7-5     VIDEO - Output to video synthesizer

        General Utility Routines
        _______ _______ ________

        8-1     MISC - Miscellaneous Routines

        8-4     LOOKUP - Symbol Table Searching

        8-5     POT - Pot reading routine

        8-7     GLBGET - Read in global data structure

        8-8     INTERP - Interrupt Package

        8-10    TELL - who has your I/O device

        8-11    SETANG - Angle conversion
                          HAND/EYE LIBRARY                        1-4


                               SYMBOLS
                               _______


        Below is  a list of  all globals, files,  and entries  in the
current library, except  for symbols used internally  between library
routines  only  (they  have  funny names)  and  files  which  have no
references  other than  themselves.  The  reference column  gives the
FILES or table of contents entry where major references to the symbol
may be  found including examples  of its use.  The first  FILE listed
contains the  definition of  the symbol.  By  referring to  the FILES
listed the  user will learn  all he needs  to know about  the symbol,
hopefully.  The type column contains the following codes:

       F     The symbol is the name of a file.

       E     The symbol is an entry point.  If the symbol  appears in
             an EXTERNAL statement in a program, the file  the symbol
             is in will be loaded during a library search of HELIB.

       G     The symbol is a global (or INTERNAL) variable.   It will
             not cause  loading of  a library  file during  a search.
             Variables in  internal procedures  are not  listed.  You
             should not be loading them.

SYMBOL                  TYPE            REFERENCE

ADCHG                   E               MISC
ADJUST                  E               MISC, BUFFER INIT, AVERAG
AVEFOC,AVEPAN,AVETIL    G               TVPOT
BCLIP                   E               GLOBAL, TV CAMERA, EYECAL
BITS                    E               GLOBAL, BUFFER INIT
BMAX                    E               GLOBAL,TV CAMERA,BUFFER INIT
BUTTON                  E               MISC
CALLEN                  E               TSERVO
CALPOT, CALSTP, CALSER  E               TSERVO
CANMAIL                 E               VIDEO
CONV                    E               TVIN
CWHEEL                  E               WHEEL
DDACO                   E               DACO
DDVID                   E               VIDEO
DIFER                   E               DIFR
DIFFOC,DIFPAN,DIFTIL    G               TVPOT
DISABL                  G               INTERP
DISPLY                  E               DISP
ENTERY,ENTERZ,ENTINT    E               ENT,ENTER,OPER
ERROR                   G               TVIN
E1, E2, E3              G               TSERVO
FADCHG                  E               MISC
                          HAND/EYE LIBRARY                        1-5


FLINE                   E               GLOBAL,TV CAMERA,BUFFER INIT
FRDCHG                  E               MISC
GENTER                  E               ENTER
GETPNT                  E               ENTER
GHISTO                  E               HISTO
GIOWD, GLABEL           E               MISC 
GRADNT,GVALUE           E               ENTER
GXCT                    E               MISC
HISTL                   E               HISTO
HISTOG                  E               DIFR
HOFF                    G               GLOBAL
HYSTAB                  E               HISTO 
IND                     G               WHEEL 
INDEX                   G               TVPOT
INTINT                  E               INTERP
INTPNT                  E               ENTER
INTWAI                  E               INTERP
IWID                    E               GLOBAL
JOBOK                   E               VIDEO
LENS                    E               TSERVO
LINLEN                  E               GLOBAL
LLINE                   E               GLOBAL,TV CAMERA,BUFFER INIT
LOCKON,LOCKOF           E               MISC
LOOKP                   E               LOOKUP
LSIDE, LSMAX            E               GLOBAL,TV CAMERA,BUFFER INIT
L1, L2, L3              G               TSERVO
MAXDIF                  G               TVPOT
NUMBR                   G               AVERAG
NXTLEN                  E               TSERVO
OB, OCL,OD              G               OPER
OPINIT                  E               OPER
ORX,ORY,OSL             G               OPER
OVERL                   E               VIDEO
PICCLS, PICOUT          E               PICWR
PICINI, PICRD           E               PICRD
PICWI, PICWR            E               PICWR
POTABS, POTREL          E               POT
POTS                    G               POT
PRNT                    E               DIFR
PRTBUF                  G               PORTR
PUTPNT                  E               ENTER
P1, P2, P3              G               TSERVO
RDCHG                   E               MISC
REF                     G               TVPOT
RSIDE, RSMAX            E               GLOBAL,TV CAMERA,BUFFER INIT
SLIM                    G               GLOBAL,ENT,OPER
SPWON,SPWOFF            E               MISC
ST                      E               GLOBAL
                          HAND/EYE LIBRARY                        1-6


STATUS                  G               TSERVO
STV                     E               GLOBAL, TVIN, ENTER, OPER
STVFL                   E               GLOBAL, ENTER, OPER
SUMFOC, SUMPAN, SUMTIL  G               TVPOT
SUPRES                  E               DIFR
TCLIP                   E               GLOBAL, TV CAMERA, EYECAL
TMAX                    E               GLOBAL,TV CAMERA,BUFFER INIT
TMPBUF                  G               AVERAG
TNOISE                  G               ENTER
TV CONTRL WORDS         G               GLOBAL
TVCAM                   E               GLOBAL, TV CAMERA
TVIN                    FE              TVIN, TV CAMERA
TVMOVE                  E               TVIN
TVOUT                   E               GLOBAL
TVREAD                  E               TVIN
TVWID                   G               GLOBAL, ENTER, OPER
TVWORD                  E               GLOBAL, BUFFER INIT, TVIN
VIDEO                   E               VIDEO
VOFF                    E               GLOBAL
                          HAND/EYE LIBRARY                        2-1


                             INTRODUCTION
                             ____________


        All subroutines used by the Hand-Eye Project are on a library
file  for  the use  of  people  writing programs  in  this  area.  By
requesting  a  library search  of  the file  when  loading,  only the
subroutines needed by the program will be loaded.

        The library file can be obtained from the author or  found on
the disk  as a system  program.  It can  be searched by  changing the
<altmode> at the end of the loader command string to

                        ,/LSYS:HELIB<altmode>

or if you are using SAIL programs include the line

                    REQUIRE "HELIB[1,3]" LIBRARY;


        The  descriptions of  the  subroutines are  in  the following
format:

     FILE:        Name of the  file containing the subroutine  if not
                  obtained  from the  library file.   It is  also the
                  program name for RAID.

     SIZE:        The  approximate   number  of  words   required  by
                  subroutine in octal.

     ENTRIES:     Internal   references  in   the   subroutine  whose
                  inclusion in an  EXTERNAL statement in  the calling
                  program will cause the program to be  loaded during
                  a  library   search.   If   this  portion   of  the
                  description does not exist for a subroutine then it
                  has one entry which  is the same as the  file name.
                  If it is included,  only the labels listed  with it
                  are entries.

     INTERNAL:    Any labels listed  here are globals defined  in the
                  subroutine which the user may wish to  reference in
                  his program.  They will not cause the program to be
                  loaded during a library search, however.   The user
                  must not  have any INTERNAL  statements referencing
                  any labels listed under ENTRIES or INTERNAL for any
                  subroutine which is loaded.  Unless noted, they are
                  type INTEGER.
                          HAND/EYE LIBRARY                        2-2


     SUBRS:       Lists of all files which this subroutine will cause
                  to  be loaded  during a  library  search, including
                  those called by subroutines it calls.

     ACS:         The contents of  any accumulators listed  here will
                  be changed by the subroutine, or the subroutines it
                  calls.

        The above will be  followed by a detailed discussion  of each
entry. For each entry the following information is given:

CALL:        A sample call in  MACRO and/or SAIL.  If only  the MACRO
             call  is given,  the  subroutine cannot  be  called from
             SAIL, even  if it has  the proper calling  sequence.  If
             only the SAIL call is given, a SAIL calling  sequence is
             used for the MACRO  call.  (See section on  SAIL calls).
             Some   procedures   use  SAIL   library   routines  and,
             therefore,  cannot  be called  unless  the  SAIL runtime
             routines are available  and a SAIL main  program exists.
             The arguments  listed here  will be  referred to  in the
             description.

DECLARATION: If  the subroutine  can be  called by  a SAIL  program a
             sample  declaration  is  given.   Note  especially which
             arguments  are called  by value.   If ANY  appears, then
             those arguments can  be either REAL, INTEGER,  STRING or
             BOOLEAN, to  conform to the  declarations in  the user's
             program.
                          HAND/EYE LIBRARY                        2-3


                        SAIL CALLING SEQUENCES
                        ____ _______ _________


        Most subroutines in the library can be called from  SAIL; new
routines have  only SAIL  calling sequences.  To  call these  from an
assembly  language  program  the following  description  of  the SAIL
calling sequence is given.

      1.   A subroutine FOO is called by PUSHJ 17, FOO.

      2.   All arguments except those declared STRING are pushed onto
           the stack pointed to by AC 17 in the order they  appear in
           the calling sequence.

      3.   Except  for arrays,  variables  called by  VALUE  have the
           contents of the cell put on the stack.  Calls by reference
           put a pointer to the variable on the stack.

      4.   The subroutine must  remove the arguments from  the stack;
           the calling program does not.

      5.   A typed procedure returns a value in accumulator 1. If the
           user does not need the value, he can declare the procedure
           as an untyped one and the value will be discarded.

           EXAMPLE:    If the declaration is

           EXTERNAL  INTEGER   PROCEDURE  FOO(INTEGER   A;  REFERENCE
                       INTEGER  B; INTEGER  C; REFERENCE  INTEGER D);
                       and the call is

                    ZA ← FOO(A,  5,  XX,  -5,  Z);

                       then the  calling sequence generated  by SAIL,
                       and  which  should be  generated  for  a MACRO
                       program is

           PUSH    17,A;               value
           PUSH    17,[[5]];           reference
           PUSH    17,XX;              value
           PUSH    17,[[-5]];          reference
           PUSH    17,[Z];             reference
           PUSHJ   17, FOO;            execute
           MOVEM   1,ZA;               store value

      6.   Arrays are  funny and will  not be described.   Except for
           GIOWD, PICRD, and PICWR, SAIL array identifiers  cannot be
                          HAND/EYE LIBRARY                        2-4


           passed to  subroutines in the  library.  To pass  an array
           FOO, the  argument must  be FOO[A], where  A is  the lower
           limit of the subscript.

      7.   Strings are passed through a special stack in AC  16, with
           the number of characters and a POINT word being given.  To
           pass a string

                     FOO : ASCII  /THIS IS TEXT/

           to subroutine DCHAR, use the following code

           MOVE   16,[IOWD 2, PDL];    2 word stack pointer
           PUSH   16,[=12];            Push count
           PUSH   16,[POINT 7,FOO];    Push pointer
           PUSHJ  17,DCHAR;            Execute

      Warning:

      1.   If you write  a MACRO program which  is to be  called from
           SAIL, you must save AC 16  and 12 on entry (AC 17  also if
           it is not used for a subroutine pushdown stack,  using the
           pointer supplied by  SAIL) and restore them  when exiting.
           They must also be  restored and saved when calling  a SAIL
           procedure from a MACRO program.

      2.   Using SAIL procedures  without a SAIL main  program causes
           problems with initialization  and should not  be attempted
           unless  you are  sure you  know what  you are  doing. SAIL
           procedures  in  the  library  are  so  indicated   at  the
           beginning of their descriptions under SIZE.
                          HAND/EYE LIBRARY                        2-5


                          IO INITIALIZATION
                          __ ______________


1.   Before calling  a library subroutine,  a pushdown  stack pointer
     must be put in AC 17 and must not be destroyed.  When the system
     has been  called during the  execution of a  library subroutine,
     the pointer must be  restored.  SAIL main programs will  do this
     for you.

2.   All TTY I/O in the library, except possibly for SAIL procedures,
     is done using the TTYSER UUO.

3.   Routines using LPT, DTA, DSK, MTA, or TV initialize  and release
     the devices.  The device assignments are:

TV=17   (TVIN)
LPT=16  (PRDUMP, DIFR)
DSK=any (PICRD,PICWR) These routines are given a channel by the user.
                          HAND/EYE LIBRARY                        2-6


                              TV CAMERA
                              __ ______


        While many users of this package will use TV images stored on
the  disk, some  work will  need to  be done  using the  camera.  The
following description of how the camera looks to the  computer should
be sufficient for most users.  The author will be glad to discuss the
camera and any of the subroutines mentioned here in more  detail with
interested users.  WARNING: the TV camera can be  damaged extensively
by improper use and failure to take certain precautions.

        The  computer  can  input a  rectangular  section  of  the TV
picture of  any shape  and size up  to the  entire picture.   For the
purpose of specifying the limits of the rectangle, a  coordinate grid
is placed on the picture,  with the origin in the upper  left corner.
The X and Y axis are both positive with X increasing to the right and
Y increasing down.  The area around the edge of the picture is always
a constant value and, therefore, need not be read.  The  useful range
of coordinates is:

                           octal               decimal
             X             12 - 505            10 - 325
             Y             17 - 372            15 - 250

         The maximum range of coordinates is:

                           octal               decimal
             X             0 - 515             0 - 333
             Y             0 - 400             0 - 256

        In the subroutines  the limits of  the rectangle read  in are
contained in  the following global  variables: (all  global variables
mentioned in this section are in file GLOBAL)


             RSIDE         right side
             LSIDE         left side
             FLINE         first (top) line
             LLINE         last (bottom) line

They must satisfy the following relationships:

             0≤LSIDE ≤ RSIDE ≤ 333(decimal)
             0≤FLINE ≤ LLINE ≤ 256(decimal)


        Otherwise, the action of the TV camera and data  channel will
                          HAND/EYE LIBRARY                        2-7


be rather strange, probably resulting in address checks or hanging up
the TV.  None of  the subroutines discussed below check  to determine
if these relationships hold, except INP.

        Also, the following inequality must hold (decimal):

      (((RSIDE - LSIDE + 1)/9)+ 1) x (LLINE - FLINE + 1) ≤ TVSIZ

where TVSIZ is  the length of the  TV buffer.  The TVIN  package will
truncate the input if this does  not hold and the bottom part  of the
rectangle  will be  lost.  The  routine does  not inform  the calling
program that this happened.

        The edge follower  and various calibration routines  can move
the rectangle to the area  they want to read.  Another set  of global
variables specifies  the outer  limits of  the area  of the  TV image
which can be read.  They are:

             RSMAX         right side
             LSMAX         left side
             TMAX          top
             BMAX          bottom

        The TV image inside the rectangle is read in line by line and
stored in a buffer.  For each  point there is a density value  in the
range 0 - 17, (octal) where 17 is the lightest and 0 is  the darkest.
The density values  are packed nine  to a word.  Each line of  the TV
scan starts in a new word. If the number of points requested per line
is not divisible by 9, the  last word is filled out by  the densities
of points immediately to the right of the area requested.

        The user can select which part of the entire density range of
the camera he wishes to input.  TCLIP and BCLIP contain the upper and
lower  clip levels,  respectively.  They  must satisfy  the following
relationship: (the subroutines do not check this)

                        0 ≤ TCLIP ≤ BCLIP ≤ 7


        When their value is 0 and 7 the entire range of  densities of
the camera is divided into  20 (octal) levels.  As BCLIP  is lowered,
the levels are  shifted toward the light  end of the range,  with the
dark areas becoming  0.  As TCLIP is  raised, the levels  are shifted
toward the  dark end  with the  light areas  becoming 17  (octal).  A
little experimentation on  the computer will  give the user  a better
idea of the effect of these variables.
                          HAND/EYE LIBRARY                        2-8


        There are several TV cameras available.  The proper camera is
selected  by  putting  its  number in  global  cell  TVCAM,  which is
assembled specifying camera one.

        The cameras are:

         0   TV on cart
         1   old COHU TV on electric arm table
         2   new tv on electric arm table
         3   TV in hydraulic arm room
                          HAND/EYE LIBRARY                        2-9


                  BUFFER AND VARIABLE INITIALIZATION
                  ______ ___ ________ ______________


        In the subroutines which require a TV buffer, it is specified
by the variable TVWORD in file GLOBAL.  The user must store in  it an
IOWD giving  the negative  of the length  in the  left half,  and the
starting address  minus one  in the  right half.   If he  has several
buffers they may be  switched as desired, remembering that  the block
of  globals starting  with BCLIP  (in GLOBAL)  and ending  with RSIDE
should contain the  numbers describing the current  buffer.  Whenever
the rectangle  size or BITS  is changed ,  subroutine ADJUST  must be
called.  If a library routine makes the change, it will call ADJUST.

        Other  buffers  are  used  by  AVERAG  and  PORTR  which  are
specified similarly.   Before using the  library, the  description of
file  GLOBAL  should  be  read.   In  the  section  labeled  "TV scan
control", the  variables BCLIP,  TCLIP, FLINE,  RSIDE may  be changed
before calling TVIN.  BITS  may be changed when calling  AVERAG.  The
rest need never be changed by the user.  The library  subroutines can
be used to set  all variables in the  file except TMAX -  RMAX (which
can be left as they are assembled) and TVWORD.
                          HAND/EYE LIBRARY                       2-10


                           GLOBAL VARIABLES
                           ______ _________

FILE:        GLOBAL
SIZE:        25
ENTRIES:     BCLIP, TCLIP, BITS,  IWID, LINLEN, FLINE,  LLINE, LSIDE,
             RSIDE,  TVWORD,  (for internal  use  only:  TVOUT), STV,
             STVFL, ST, BMAX, TMAX, LSMAX, RSMAX, TVCAM,  SLIM, HOFF,
             VOFF
ACS:         none

        This  file  contains  global  variables  referred  to  by the
library subroutines.   If the  initial value (below)  is blank  for a
variable, it must be initialized by the user before subroutines using
it are called.

     VARIABLE        INITIAL VALUE   DESCRIPTION

                     (INTERNAL VARIABLES)

     TVOUT           --      TV  buffer  pointer  set  by  subroutine
                             ADJUST

                     (TV SCAN CONTROL - ASSEMBLED IN ORDER GIVEN)

     BCLIP           7       Bottom clip level

     TCLIP           1       Top clip level

     BITS            4       Sample width (set by TVIN)

     IWID            53      Samples per line (set by TVIN)

     LINLEN          0       Words  per  TV  line  (set  by  TVIN and
                             ADJUST)

     FLINE           100     TOP (first) line

     LLINE           200     BOTTOM (last) line

     LSIDE           200     Left side

     RSIDE           300     Right side

                     (BUFFER CONTROL)

     TVWORD                  Specifies TV buffer
                          HAND/EYE LIBRARY                       2-11



                     (TV IMAGE LIMITS - ASSEMBLED IN THIS ORDER)

     TMAX            15      Lower limit of FLINE

     BMAX            372     Upper limit of LLINE

     LSMAX           10      Lower limit of LSIDE

     RSMAX           505     Upper limit of RSIDE

                     (MISC. VARIABLES)

     TVCAM           1       TV camera in use

     TVWID           101     TV Frame width

     STV             0       Nonzero if TV input converted  from grey
                             code (see ENTER).

     STVFL           0       Nonzero if TV buffer full(see ENTER).

     ST              0       Nonzero  if  disk  input  instead  of TV
                             (used by edge follower)

     SLIM            0       Nonzero  if flexable  limits on  tv scan
                             (see ENT).

     HOFF            0       Nonzero  for  horizontal  offset  of  TV
                             image

     VOFF            0       Nonzero for vertical offset of TV image
                          HAND/EYE LIBRARY                        3-1


         TSERVO - SERVO ROUTINE FOR PAN,TILT, FOCUS (camera 1
         ______ _ _____ _______ ___ _________ _____ _______ _

FILE:        TSERVO
SIZE:        321
ENTRY:       TSERVO, CALPOT, CALSTP, CALLEN, NXTLEN, CALSER
INTERNAL:    STATUS, LENS, P1, P2, P3, L1, L2, L3, E1, E2, E3, REF
ACS:         1

        The COHU TV used by the hand-eye programs has four  motors on
it  which are  under computer  control; one  to pan  the TV  left and
right, one to tilt  it up and down, one  to move the vidicon  tube in
and out to provide focusing, and one to move the turret to select one
of the four  lenses mounted on it.   The pan, tilt, and  focus motors
are connected to potentiometers which allow the computer to determine
the position of the motors.   The turret motor turns the turret  in a
counterclockwise  motion as  you face  the camera.   If the  motor is
stopped after the turret starts to move, it will continue to the next
position.


                              POT LIMITS


        This routine will move the pan, tilt, and focus motors to any
desired position as well as change lenses.  The user, in his program,
starts the servo program, which  runs in spacewar mode, and  gives it
the desired position.  For maximum accuracy, the routine expects, and
returns, the  ratios of  the pot readings  to the  reference voltage.
Users  should do  their  calculations using  these ratios  if  at all
possible.   The  reference  voltage,  and  thus  the   pot  readings,
fluctuate widely over periods longer than a few minutes, and only the
ratios will remain relatively constant.  It is up to the user to make
sure  that the  readings given  can be  reached by  the  motors.  The
maximum and minimum values are (in decimal)

     focus  far         2048
            near        0

     tilt   up          2000
            down        -1884

     pan    right       2048 (in direction camera is facing)
            left        -2000

        The  limits  for  the  tilt  and  focus  motors  are  set  by
mechanical stops.  The pan motor, however, can turn 350  degrees and,
if allowed  to servo to  a reading outside  of the given  stops, will
damage the cables to it. (This routine does not check limits)
                          HAND/EYE LIBRARY                        3-2


                            SERVO CONTROL


        Communication  with  the  servo  routine  is  accomplished by
altering bits in a status  word in the servo routine.   Various other
words in the routine may be of interest to the user.  They  are given
below: (all except STATUS and LENS are floating point numbers)

      STATUS Holds status  bits for  communication betweeen  user and
             servo routine.

      LENS   For lens changing.

      REF    final reference voltage reading

      P1     Ratio of latest focus pot reading/reference voltage

      P2     Ratio of latest tilt pot reading/reference voltage

      P3     ratio of latest pan pot reading/reference voltage

      L1     Ratio of final focus pot reading/reference voltage

      L2     ratio of final tilt pot reading/reference voltage

      L3     Ratio of final pan pot reading/reference voltage

      E1     Focus tolerance (assembled as 4.0)

      E2     Tilt tolerance (assembled as 10.0)

      E3     Pan tolerance (assembled as 10.0)

        The last three  cells determine how  close Pi*REF must  be to
Li*REF to stop  servoing.  They may be  increased, but should  not be
decreased as this will greatly shorten the life of the relays  in the
controller.

        The  bits in  STATUS which  are used  by the  routine  are as
follows:

BIT      NAME  USE
___      ____  ___

               GENERAL BITS

1        DONE  Set by TSERVO when all actions have been  completed or
               an error condition has been detected.  While it is on,
                          HAND/EYE LIBRARY                        3-3


               the routine idles  clearing the time  counters, making
               sure  all motors  are off,  and setting  the  RUN bit.
               This bit is  never cleared by  the routine.  If  it is
               not set all error bits will be cleared each tick.

2        RUN   Set  each  tick by  TSERVO.   It is  never  cleared or
               tested.

         REQUEST BITS

4        READ  (POT READ REQUEST) If this bit is on, the  current pot
               readings  are read  and  the readings  divided  by the
               reference voltage  reading are stored  in P1,  P2, and
               P3.  If no other request bits are on the DONE bit will
               be set immediately.  This bit is never cleared  and it
               can cause bits MISS, ADH, GHANG to be set.

10       SERVO (SERVO REQUEST) If this bit is set the pan,  tilt, and
               focus motors are servoed  until they are within  Ei of
               Li*REF.   The  last   pot  readings  divided   by  the
               reference voltage reading will be in P1-P3.   When all
               motors are finished, this bit will be  cleared, unless
               an error  occurs first.   If READ is  set, it  will be
               ignored.  This  bit can cause  bits MISS,  ADH, FHANG,
               THANG, PHANG, GHAND to be set.

20       LENS  (LENS CHANGE REQUEST) If  this bit is set,  the turret
               is moved to the lens specified by the low  order three
               bits of LENS.  If this lens is in position,  no motion
               will occur.  If LENS<0, the next lens in sequence will
               be moved into position  and its number put  into LENS.
               If an  error occurs,  the turret may  or may  not have
               moved; it will not stop between lenses.  In  this case
               the requested lens may not be in position and LENS may
               not contain the correct lens number.  This bit will be
               cleared  when the  proper lens  is in  position  if an
               error has  not occured.   If both  LENS and  LREAD are
               set, LREAD is ignored.  This bit can cause  bits LHAND
               and GHANG to be set.

40       LREAD (LENS READ  REQUEST) If this  bit is set,  the current
               lens number  is put into  LENS.  If only  LREAD and/or
               READ are  set, the DONE  bit will be  set immediately.
               This bit is never  cleared and can cause bit  GHANG to
               be set.

         ERROR  BITS  (DONE  bit always  set,  counters  cleared, and
               motors turned ofF)
                          HAND/EYE LIBRARY                        3-4


100      MISS  136  data  channel  has  missed  data  for  25 (octal)
               consecutive reads.  This is either a hardware error or
               somebody else is using the A-D converter.

200      ADH   The A-D converter is  hung. Same problems as  for MISS
               or PDP-6 is not running.

         (The  rest of  the errors  are controlled  by  time counters
               which are cleared whenever the DONE bit is set)

400      LHANG Lens  change  did  not  terminate  withing  4 seconds.
               (Hardware problem)

1000     FHANG The focus motor was not moving for 1 second and is not
               at  its final  position;  assumed hung.   This  can be
               caused  by  a  hardware problem  (what  can't  !!), by
               hitting a stop, or because the controls are in manual.
               The  not  moving  tests  are  controled  by  the error
               tolerences E1-E3.

2000     THANG Tilt motor hung. See FHANG.

4000     PHANG Pan motor hung.  See FHANG.

10000    GHANG TSERVO did not set the DONE bit withing 20  seconds of
               the  time it  was  started or  the DONE  bit  was last
               cleared.  This is  either a hardware  problem, program
               bug, core garbaging, or someone else is using  the A-D
               (see below)

         CONDITION BITS

100000   CONFL This bit is set if  TSERVO had to skip a  tick because
               someone  else was  using the  A-D.  Lens  changing and
               reading pots  or the  lens are  not affected.   If the
               other user hangs on to the A-D, the GHANG flag  may be
               set.

        When the  user's program  wants to servo,  it sets  STATUS as
desired and executes

        SPCWAR          0,636367        (in assembly languages)
        SPCWAR          1,TSERVO

or

        SPWON(1,TSERVO)                 (in SAIL - see file MISC)
                          HAND/EYE LIBRARY                        3-5


to start spacewar mode.  The opcode SPCWAR is [43B8].  When  the DONE
bit is  set all actions  are completed.  The  routine will  then idle
until the DONE bit is cleared again or spacewar mode is turned off.

        When finished with the servo routine, make sure the  DONE bit
has been set by the servo routine and then execute SPCWAR 0,636367 to
turn it off (SPWOFF to SAIL).

        It  is  very  important  to note  that  once  the  motors are
started, calling the system or  killing your job will not  stop them.
They can be  stopped temporarily by  putting the controls  in manual,
which  will cause  them to  be  turned off  if the  servo  routine is
running.   Otherwise  they will  start  again when  the  controls are
switched back to  computer control.  The only  way the motors  can be
stopped when the  servo routine is not  running is by  executing CONO
700,40, in spacewar mode  or by executing procedure  CALSTP mentioned
below.

        It  should also  be  noted that  the action  of  the routine,
especially the lens change,  may change as the timesharing  system is
changed.  An attempt  will be made to  keep it updated to  the newest
system in use.

        The  following routines  allow the  user to  do a  few useful
things without having to mess with spacewar mode directly.


CALL:        CALSER;                                 (SAIL)
             PUSHJ 17,CALSER(MACRO)

DECLARATION: EXTERNAL PROCEDURE CALSER;

        The first time it is called after the program is  loaded, the
ratios of the current  pot readings to the reference  voltage reading
are  stored  in L1,  L2,  and L3.   Thereafter,  if the  TV  is under
computer control, it will be servoed to the set readings.  If  the TV
is in  manual, the  current pot  readings will  again be  saved.  The
error bits will not be checked.


CALL:        CALSTP;                                 (SAIL)
             PUSHJ 17,CALSTP;                        (MACRO)

DECLARATION: EXTERNAL PROCEDURE CALSTP;

        CALSTP  makes sure  all motors  are off.   It also  turns off
spacewar mode.
                          HAND/EYE LIBRARY                        3-6




CALL:        CALLEN;                                 (SAIL)
             PUSHJ 17.CALLEN;                        (MACRO)

DECLARATION: EXTERNAL PROCEDURE CALLEN;

        CALLEN reads  the position of  the turret without  moving it,
and stores the lens number in LENS.


CALL:        NXTLEN;                                 (SAIL)
             PUSHJ 17,NXTLEN                         (MACRO)

DECLARATION: EXTERNAL PROCEDURE NXTLEN;

        NXTLEN moves the turret to the next lens position  and leaves
the lens number in LENS.  Error bits are not checked.


CALL:        CALPOT;                                 (SAIL)
             PUSHJ 17,CALPOT                         (MACRO)

DECLARATION: EXTERNAL PROCEDURE CALPOT;

        CALPOT puts the current pot readings/reference voltage in P1,
P2, and P3.
                          HAND/EYE LIBRARY                        3-7


                        EYECAL -TV CALIBRATION
                        ______ ___ ___________

FILE:        EYECAL
SIZE:        276
CALLS:       GLOBAL, ENTER, TVIN, QUAM DISPLAY ROUTINES, SAIL RUNTIME
             ROUTINES ,POT,TELL
ACS:         ALL


CALL:        EYECAL(BUF_SIZ,FRAME,FLAG,BUFFER);      (SAIL)

DECLARATION: EXTERNAL PROCEDURE EYECAL(INTEGER BUF_SIZ,FRAME,FLAG;
                 INTEGER ARRAY BUFR);

        BUFR is a display buffer for the QUAM display routines, which
must be loaded.  BUF_SIZ is the size of the buffer, and FRAME  is the
piece-of-glass number  the routines are  to use.  The  routine starts
with the verify operation if FLAG is FALSE, or manual if it  is TRUE,
and will accept the letters V, M or Y (no carriage return  needed) at
any time to  switch to another  operation.  All other  characters are
ignored.

        The operations are:

      Y    finished - Return to the calling program.

      M    manual - Continuously  scan one line  of the TV  image and
           display a position vs. intensity graph on the  CRT.  TCLIP
           and BCLIP are set  to 7 initially.  Arrows on  the display
           indicate  the  position of  intensities  0 and  17  in the
           graph.  Pot 12 moves the  scan line up and down.   Pots 14
           and 15  alter BCLIP  and TCLIP,  whose current  values are
           displayed.  The program will not allow their values  to go
           outside the permissible limits or for BCLIP to become less
           than TCLIP. The pots are read in absolute mode.

      V    verify - Same as  manual only the currently  stored values
           of TCLIP and BCLIP are used to start.

        This subroutine  requires a  TV buffer  at least  140 (octal)
words long and a display buffer at least 350 (decimal) words long. It
scans the TV image, using  TMAX, BMAX, RSMAX and LSMAX as  the limits
of the image.  When it exits, LLINE, FLINE, RSIDE, and LSIDE  are set
to the limits of the last  line read from the TV. If the  pot routine
cannot initialize the AD, a message will be typed.

        WARNING If  called from an  assembly language routine,  AC 16
        _______
must have a pointer to the SAIL string pushdown list.
                          HAND/EYE LIBRARY                        3-8


                     DACO - SET TV TARGET VOLTAGE
                     ____ _ ___ __ ______ _______

FILE:        DACO
SIZE:        273
ENTRY:       DDACO
SUBRS:       TELL
EXTERNAL:    AUTO_ACC, DAC_ACC
ACS:         0-6


CALL:        VAL←DDACO(DACR);                        (SAIL)

             PUSH 17,DACR
             PUSHJ 17,DDACO                          (FAIL)
             MOVEM 1,VAL

DECLARATION:EXTERNAL INTEGER PROCEDURE DDACO(INTEGER DACR);

        The  target voltage  of the  COHU TV  camera can  be changed,
under program control, to  vary the camera's sensitivity.   A digital
to analog converter (DAC) can be set to numbers in the range  0-63 to
adjust the target voltage, where  0 is the most sensitive and  63 the
least (actually  62 is the  highest number which  should be  used; on
some days of the week 63 causes a negative target voltage).   The DAC
is only effective if the TV sensitivity control, on the box under the
hand/eye  table, is  in auto  mode.  In  this mode,  the  TV hardware
generates a voltage based on the average brightness of the scene (the
auto target voltage or ATV) which will normally be the target voltage
used  by the  TV.  To  protect the  vidicon, the  DAC cannot  set the
target  voltage higher  than  the ATV  (which  is set  by  a hardware
adjustment made only by experts).  The target voltage is connected to
an analog to digital converter (AD) which allows programs to read it.
Thus, if the DAC is set  to 62 and then decremented toward 0,  the AD
readings  will decrease  until  the ATV  is reached  and  then remain
approximately constant  as the  DAC is  decremented further.   Due to
noise  problems, settling  times,  and instability  in  the hardware,
accurate AD readings are hard to obtain and the  relationship between
the DAC settings and AD readings varies from run to run.

        To solve all (?) of your problems with this kludge, DDACO was
created.  If DACR≥0 the  low order six bits  will be used to  set the
DAC.  If DACR<0 the DAC will not be changed.  Once set, the  DAC will
stay set until  changed by a program  or cleared by a  hardware reset
when the system is started.

        The  current  AD reading  is  returned as  the  value  of the
procedure. It will be in the range 0-4096.  If DACR<0, the reading is
                          HAND/EYE LIBRARY                        3-9


returned in  one tick  (1/60th of a  second).  If  the DAC  was being
changed  also,  the  procedure waits  until  the  target  voltage has
stabilized to within a tolerance, which will take from 40  ticks (2/3
sec.) to  over 130 ticks  (2 1/6 sec.).   The time and  tolerance are
functions of the direction of the change, the size of the change, and
the nearness  of the new  DAC setting to  the ATV.  The  tolerance is
much higher when the DAC is  near the ATV, due to oscillation  in the
ATV.  If the DAC setting is changed from below to above the  ATV, the
settling time will be near the upper limit; it will be near the lower
limit otherwise.  DDACO runs in spacewar mode.

DDACO ERRORS
_____ ______

        There  are three  error messages  from DDACO,  each  of which
gives you  the option  of trying again  or continuing.   The messages
are:

      DATA MISSED ON 25 CONSECUTIVE TRIES - AD ---- The AD  is unable
           to read  the target  voltage.  This  is either  a hardware
           error or another program is using the AD at the  same time
           (DDACO does not INIT is AD before using it).  Try again or
           find  a  technician.  Continuing  will  give  an incorrect
           reading.

      HUNG DEVICE AD ---- The A-D will not run.  See above error.

      DACO  TIMED  OUT  ----  DDACO  ran  4  seconds  without  the AD
           settling.  Retrying will give a good reading  (hopefully -
           it will not give the error message again).  Continuing may
           give a good reading.

USING DDACO
_____ _____

        This procedure must know the current DAC setting and ATV when
entered  to  function  properly.   These  are  contained  in integers
DAC_ACC and AUTO_ACC (see below)  which must be provided by  the user
if the  global model (PREAMB.SAI[II,HE])  is not in  use and  must be
initialized by the  user (see below).   Always use this  procedure to
change the DAC so it can update these variables.

INITIALIZING THE ATV
____________ ___ ___

        A procedure exists which will initialize DDACO by finding the
ATV and  setting the DAC  to it.   It is called  SENSINIT and  can be
obtained from me.  It takes  no arguments and uses all of  the global
variables  listed  below, provided  by  PREAMB.SAI or  the  user. The
proper way to call SENSINIT at the start of each run is
                          HAND/EYE LIBRARY                       3-10


              IF ¬SENSCAL_ACC∨CHANGE_ACC THEN SENSINIT;


        After the first call, additional calls of SENSINIT will check
the ATV and change AUTO_ACC if necessary.

GLOBAL VARIABLES
______ _________

        The following  variables in the  global model should  be kept
updated by programs using  the hand/eye system.  Those needed  by the
above procedures must  be provided by the  user in an outer  block if
the global model is not available.

     AUTO_ACC      DAC setting which corresponds so the ATV.   Set by
                   SENSINIT and used by DDACO.

     AUTOCAL_ACC   TRUE if  array TABLE_ACC  has been  initialized by
                   SENSINIT, which sets and uses it.

     DAC_ACC       the  current  DAC setting.   Set  by  SENSINIT and
                   DDACO and used by both.

     CHANGE_ACC    TRUE if the  scene has changed (i.e.  objects have
                   been  moved,  the color  filters  changed,  or the
                   lights  changed).  Used  and cleared  by SENSINIT.
                   Must be set by user.

     TABLE_ACC     an  array  [0:63]  indexed  by  DAC  settings.  It
                   contains AD  readings for  all DAC  settings which
                   have been used; -1 for other settings.  Values are
                   valid only for indicies ≥AUTO_ACC.

     SENSCAL_ACC   TRUE if SENSINIT has been called.

        Note that  if you  are running with  a shared  global segment
other jobs may  be using and  changing these values.   The procedures
are aware of this and will do the right thing if you do not mess with
the variables or change the DAC with other routines.

INTERACTION WITH OTHER USERS

        This program reads the  A-D in spacewar mode  without INITing
it. The procedure  will get it even  if other users have  assigned or
INITed it.  If  another user has the  A-D when this program  wants to
read it, DDACO will wait.  If  the other user keeps it too  long, you
will  get the  "DACO  TIMED OUT"  error  message and,  in  addtion, a
message will be typed out telling  you the job number and PPN  of the
job which has the AD inited so you can yell at them.
                          HAND/EYE LIBRARY                       3-11


                   WHEEL - COLOR WHEEL MANIPULATOR
                   _____ _ _____ _____ ___________

FILE:        WHEEL
SIZE:        170
ENTRY:       CWHEEL
INTERNAL:    IND
ACS:         0-4


CALL:        TEST←CWHEEL(CODE);                      (SAIL)

             PUSH 17,CODE
             PUSHJ 17,CWHEEL                         (FAIL)
             MOVEM 1,TEST

DECLARATION: EXTERNAL BOOLEAN PROCEDURE CWHEEL(INTEGER CODE);

        This routine changes and interrogates the color wheel  on the
TV  camera.  On  exit,  IND contains  a number  0-3  specifying which
filter is in position according to the codes below.  CODE  is decoded
as follows:

    0    position red filter

    1    position blue filter

    2    position green filter

    3    position clear filter

    4    automatic - the first time called you get the  clear filter.
         Successive calls (without calls using codes 0-3  in between)
         get you blue ,red, and green, in that order.  The cycle will
         repeat indefinitely.

    5    Same as 4  except you never get  the clear filter.  4  and 5
         can be intermixed but the clear filter will be  skipped only
         if 5 is used when it was next up.

    6    Put  the filter  number (0-3)  which is  in position  in IND
         without  changing filters.   The  other codes  also  set IND
         automatically.

        If  the color  wheel  cannot be  moved to  the  proper filter
(power is off or a mechanical problem) a message is typed and you are
given a chance to retry it, or continue.  The procedure  returns TRUE
if the requested  action was successfully  carried out; FALSE  if you
continued from the error message.
                          HAND/EYE LIBRARY                       3-12


               TVPOT - read motor pots while reading TV
               _____ _ ____ _____ ____ _____ _______ __

FILE:        TVPOT
SIZE:        300
ENTRIES:     POTSET, NOPOTS
SUBRS:       GLOBAL, TVIN
INTERNAL:    MAXDIF, AVEREF, AVEPAN, AVETIL, AVEFOC,  AVZOOM, AVIRIS,
             DIFREF, DIFTIL, DIFPAN, DIFFOC, DFZOOM, DFIRIS, INDEX
ACS:         1

        TVPOT  reads  the  pan, tilt,  focus,  iris  (soon  on Sierra
camera),  and zoom  (Sierra camera)  pots continuously  while  the TV
camera is being read and returns information which will tell the user
the location  of the camera  when it  was read, as  well as  how much
mechanical jitter was observed.


CALL:        POTRED(TOLER);                          (SAIL)

             PUSH 17,TOLER
             PUSHJ 17,POTRED;                        (FAIL)

DECLARATION: EXTERNAL PROCEDURE POTRED(INTEGER TOLER);

        POTRED  deposits subroutine  calls to  TVPOT into  the TVREAD
procedure  in  file TVIN  to  synchronize pot  and  TV  reading.  The
program will  read the  pots associated with  the camera  being read.
After the  TV reading procedure  has returned, several  variables are
available for the user.

        The absolute value of the differences between the maximum and
minimum readings for each pot are stored as integers in:

     DIFREF   for the reference voltage which was applied to the pots
              read

     DIFPAN   for the pot on the pan motor

     DIFTIL   for the pot on the tilt motor

     DIFFOC   for the pot on the focus motor

     DFIRIS   for the  pot on  the iris motor  (Sierra camera  only -
              when implemented)

     DFZOOM   for the pot on the zoom lens motor (Sierra camera only)
                          HAND/EYE LIBRARY                       3-13


     MAXDIF   contains the largest of the above integers.  As long as
              MAXDIF>TOLER, the TV will be read again.

     INDEX    contains the number of times the pots were read,  as an
              integer.

        In  addition, the  average readings  are stored  in  the REAL
variables AVEREF, AVEPAN, AVETIL, AVEFOC, AVZOOM, and AVIRIS.

        The following  error messages may  appear from  TVIN routines
when pot reading is enabled (see TVIN for error recovery).  The first
two try again, the rest halt.

     POTS TOO NOISY - could not get MAXDIF<TOLER after many tries.

     AD DATA MISSED - A-D converter missed data on many tries.

     SPCWAR JOB HUNG - Pot  reading routine timed out after  about 16
                   sec.  Someone else has the A-D tied up.

     AD IS HUNG - A-D timed out without setting done flag.

     MAIN JOB HUNG ON EXIT - read pots 500 times and TV input routine
                   has  not returned  from  system call  to  start TV
                   reading.  Usually you get about 30 pot readings.

     TVCAM≠1 or 2 and POTREAD - You tried to read a camera other than
                   1  or 2  with  pot reading  set up.   Turn  it off
                   first.


CALL:        NOPOTS;                                 (SAIL)

             PUSHJ 17,NOPOTS                         (FAIL)

DECLARATION: EXTERNAL PROCEDURE NOPOTS;

        Turns off pot  reading by replacing procedure  calls inserted
into TVIN with no-ops.
                          HAND/EYE LIBRARY                        4-1


                  INP - VARIABLE TV INPUT SUBROUTINE
                  ___ _ ________ __ _____ __________

FILE:        INP
SIZE:        145
SUBRS        TVIN, MISC, GLOBAL, POT, TELL
ACS:         ALL


CALL:        INP;(SAIL)

DECLARATION: EXTERNAL PROCEDURE INP;

        This  subroutine allows  the user  to position  the  TV input
using the  pots.  The  TV camera  is read  continuously and  the pots
checked as follows:

      POT  Action
      ___  ______
      12   Move left and right sides together
      13   Move top and bottom sides together
      14   Move top side
      15   Move right side

        Note HINT FOR POT USERS under file POT.

        Thus 12 and 13 move the rectangle while 14 and 15  change its
size.  If the  result of  the change  would be  to move  part  of the
rectangle outside the TV input area, to make opposite sides cross, or
to make the rectangle so large that it would overflow the  TV buffer,
the rectangle  is adjusted to  be legal but  as close as  possible to
your request.  If the area is too large, lines are dropped off of the
bottom of the image.  Typing any character on the TTY will  cause INP
to return.  This routine sets FLINE, LLINE, etc. to the limits of the
rectangle. If this is used to set the image limits for routines which
use TMAX, BMAX, etc. (such as EYECAL and ENTER), they must be  set by
copying from FLINE, etc.

        If  the AD  cannot  be initialized  for reading  the  pots, a
message will be typed.
                          HAND/EYE LIBRARY                        4-2


                      TVIN - TV INPUT SUBROUTINE
                      ____ _ __ _____ __________

FILE:        TVIN
SIZE:        200
ENTRIES:     TVIN, TVREAD, CONV, TVMOVE
SUBRS:       MISC,GLOBAL
INTERNAL:    ERROR
ACS:         NONE


TV CONTROL WORDS (see also pages 2-6 and 2-10)

        The following integers control the reading of the TV camera:

BCLIP    is the bottom level of the range of picture densities  to be
         digitized.  It must be in the range TCLIP≤BCLIP≤7.

TCLIP    is the top  level of the range  of densities. It must  be in
         the range 0≤TCLIP≤BCLIP.

FLINE    the TV hardware scans the  image from top to bottom  and, on
         each scan line, from left to right, inputting  the densities
         at each point of the  scan within a rectangular area  of the
         image selected  by the user.   FLINE is the  first (highest)
         scan line to input.  It defines the top of the rectangle and
         must be in the range 0≤FLINE≤LLINE.

LLINE    is the  last (lowest)  scan line to  input.  It  defines the
         bottom  of   the  rectangle  and   must  be  in   the  range
         FLINE≤LLINE≤256.

LSIDE    is the first  (leftmost) sample to  read on each  line being
         read.  It defines the left side of the rectangle and must be
         in the range 0≤LSIDE≤RSIDE.

RSIDE    is the last  (rightmost) sample to  read on each  line being
         read.  It defines the  right side of the rectangle  and must
         be in the range LSIDE≤RSIDE≤333.

TVWORD   defines  the buffer  the user  has provided  to read  the TV
         image  into.  The  left  half word  is the  negative  of the
         length of the buffer.  The  right half is one less  than the
         address of  the first word  of the buffer.   Library routine
         GIOWD will  produce such a  word, given a  SAIL array  to be
         used as a buffer.

TVCAM    is the number of the TV camera to read.  The currently valid
                          HAND/EYE LIBRARY                        4-3


         numbers are 0=TV on  cart, 1=COHU camera on  hand/eye table,
         2=Sierra TV on  hand/eye table, 3=portable TV  usually found
         somewhere in machine room.  If you do not change  this word,
         camera 1 will be used.

HOFF     The TV  cameras have twice  as many points  per line  as the
         hardware can read at one time.  The addressable  range given
         above is 0-333 but there  are 666 points per line.   For any
         single  read,  the  program inputs  every  other  point from
         LSIDE*2 through RSIDE*2.  If HOFF is not zero, the  image is
         offset one  point to the  right and the  points read  in are
         LSIDE*2+1   through   RSIDE*2+1.   It   makes   very  little
         difference which  way this word  is set for  normal reading.
         It  is  included mainly  for  people who  would  like double
         resolution and who can  now read in the same  rectangle with
         the  switch  set  each way  and  interleave  the  two images
         properly.  Please  note that TVIN  will not  interleave them
         for you.

VOFF     The  cameras  also have  twice  as many  scan  lines  as the
         hardware can read at once.  Normally the even scan lines are
         read starting at FLINE*2.  If VOFF is not zero, the odd scan
         lines are  read starting at  FLINE*2+1.  Combined  with HOFF
         this gives you double resolution along both axis,  with four
         possible images for a given rectangle.


CALL:        TVMOVE                                  (SAIL)

DECLARATION: EXTERNAL PROCEDURE TVMOVE;

        TVMOVE  initializes  the  TV camera  for  reading,  using the
control words listed above.  It must be called before reading  the TV
the first  time and,  thereafter, whenever any  of the  control words
have been  changed.  The  control words are  truncated to  the proper
number of bits  but are not otherwise  tested for correct  values. If
the  restrictions on  the  clip levels  and limits  of  the rectangle
mentioned  above are  violated,  one or  more of  the  following will
occur: the system will  respond with an ADDRESS CHECK  error message,
incorrect information will be put in the buffer, the wrong section of
the TV image will be read, or attempts to use the contents of  the TV
buffer will wipe out the program.

        If the number of words necessary to hold the entire  image is
greater than specified  by TVWORD, the bottom  of the image  is lost.
The size  of the  image read  in, by  TVREAD, is  the minimum  of the
length of  the TV  buffer and  the size  computed from  the rectangle
limits.
                          HAND/EYE LIBRARY                        4-4


        The  following words  are set  by TVMOVE  and left  for other
library routines:

BITS     is the number of bits per sample.  It is always set to 4.

IWID     is the number of samples read per line.  It is set to RSIDE-
         LSIDE+1.

LINLEN   is the  number of full  words read per  line.  It is  set to
         IWID/BITS rounded up to the next larger integer.

        CANNOT INIT TV is typed if TVMOVE has failed 20 times to open
an I/O channel for the TV camera. This usually means someone  else is
using it. There is only  one TV interface so opening the  channel for
any  TV prevents  other programs  from using  any of  them  until you
release your channel. Typing any character causes the routine  to try
another 20  times. The TV  will be opened  on channel 17  (octal) and
will left open on exit for TVREAD, which actually reads in the image.
TVMOVE can be called again without releasing the channel.


CALL:        TVREAD;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE TVREAD;

        TVREAD reads in one TV image on each call.  It assumes TVMOVE
has been called to set up the control words and open the channel, but
does no checking.  The image is read into the user's  buffer starting
with the top scan line specified and reading points  into consecutive
locations in the  buffer, nine four bit  samples per word.   The last
word of each line is filled out with the necessary number  of samples
from the line to the right of RSIDE, so that each scan line is stored
beginning  at a  word boundary.   The area  read appears  as  a white
cursor on the monitor.  The cursor shows the position in the image of
three sides of the rectangle you specified, namely FLINE,  LLINE, and
LSIDE.  The right  side of the  cursor, however, is  LINLEN*9 samples
from LSIDE,  which will  be slightly  to the  right of  RSIDE, unless
RSIDE is a multiple of nine.

        There are  four error  messages associated  with the  TV.  TV
DATA MISSED-TVIN is typed when the data channel has missed data on 50
consecutive attempts to read  the camera.  The program will  then try
another 50 times.   PARITY ERROR is typed  when 10 parity  errors are
counted  without  a  successful  read.   This  indicates  a  hardware
malfunction.   Again, the  program  will keep  trying,  although with
small chance for success.  SYS ERR -TVIN is typed when the NON-EX MEM
flag is  on in the  data channel and  usually means the  time sharing
                          HAND/EYE LIBRARY                        4-5


system is sick and may die.   TV IS HUNG-TVIN is typed if  the system
thinks the TV interface is hung.  Normally, in the case of these last
two messages, the program halts.   You should be able to  CONTINUE if
you  think  things  are  all right.   If  internal  integer  ERROR is
nonzero,  however, the  program will  keep retrying  after  any error
message.

        TVREAD can be called as often as desired, but,  unless TVMOVE
is called in between, will read the same image each  time, regardless
of  how the  TV control  words are  changed.  This  allows  very fast
reading of the TV, mainly to keep the cursor displaying.  It can also
be used when the TV  image is being changed by hardward,  rather than
the  control words.  Such changes  include the  position of  the pan,
tilt, and focus motors and the color wheel (on Sierra or COHU cameras
only), camera sensitivity and  lens (COHU only), the position  of the
zoom lens (Sierra only), and, soon, the iris on both cameras.

        It is possible to continuously read the pan, tilt,  and focus
pots while  reading either camera  1 or 2.   Usually this is  done to
determine  the  amount  of  vibration  in  the  camera   mount,  and,
therefore,  the  amount  of  jitter  introduced  into  the  image for
applications requiring very good images.  If this feature  is needed,
read the section on TVPOT.   You will not get this feature  unless it
is specifically requested.

        Two final warnings.  TVREAD  does not release the  channel so
other users  cannot access TV  cameras while it  is running.   If you
call TVMOVE and TVREAD directly, rather than through TVIN, below, you
must release channel 17 (octal) when you are done reading if you want
to allow other users to run with you.  Also, TVREAD fills  the buffer
with  grey coded  densities,  not the  actual densities  you  need to
process the data.  Some of the buffer access routines in  file ENTER,
namely GENTER,  will automatically convert  the points you  access if
they have not  been previously converted.  Normally,  however, before
using the buffer, you should call CONV to convert the code.

        Before exiting,  TVREAD clears  flag STV  and set  flag STVFL
(see file GLOBAL).


CALL:        CONV;                                   (SAIL)

DECLARATION: EXTERNAL PROCEDURE CONV;

        CONV converts the contents of the TV buffer from grey code to
binary if STV is cleared, and sets STV; otherwise it does nothing.
                          HAND/EYE LIBRARY                        4-6




CALL:        TVIN;                                   (SAIL)

DECLARATION: EXTERNAL PROCEDURE TVIN;

        For users  who do not  want to worry  about all of  the above
routines,  and who  either are  changing the  control words  for each
read, or who  do not mind the  program running slightly  slower, TVIN
calls, in sequence, TVMOVE, TVREAD, CONV and releases the channel.
                          HAND/EYE LIBRARY                        4-7


                   PICRD - INPUT FROM DISK STORAGE
                   _____ _ _____ ____ ____ _______

FILE:        PICRD
ENTRIES:     PICINI, PICRD, PICDES, PICLIN
SIZE:        377
SUBRS:       MISC, GLOBAL, SAIL runtime routines
ACS:         ALL

                             FILE FORMAT


        The new disk picture I/O routines use a new and more flexible
format for  picture files.   Each file is  considered to  contain one
picture, which may  have been taken  through several filters,  or two
cameras (stero), or have been operated on, with the results stored in
the file.  In the  file is header information describing  the picture
size (BITS, LINLEN, FLINE, LLINE, LSIDE, and RSIDE) and  data blocks.
A data block is  a collection of data  which is processed by  the I/O
routines as a single entity. I.E., it must be read in or  written out
all at once; one cannot read  in portions of a data block.   The user
can specify  anything he wants  as data blocks  for output,  but many
data blocks have been reserved for specific things and are recognized
as  such by  programs  using the  picture files.   The  standard data
blocks are the picture through each of the four filters  (and through
two cameras if a stereo  picture), the camera transform, and  a title
and description.   Each disk file  may contain as  few or as  many of
these data blocks as desired.  The input routine will tell the caller
which data blocks are contained  in the file and allow him  to select
the ones he  wants.  The first part  of the file contains  the header
variables  described   above  and   data  block   descriptors.   Each
descriptor specifies where in the file the data block starts  and how
long it is.  The contents of the reserved data blocks  are determined
by  the  order  of  their  descriptors  in  the  file.   Below  is  a
description of the file format, of interest mainly to people who want
to write their own I/O routines.

    WORD   DECRIPTION
    ____   __________
    0      -1  if new  format file  (a real  -1, not  just negative);
           anything else for old format files
    1      BITS (see  TV control  word section of  file GLOBAL  for a
           description of these words)
    2      LINLEN
    3      FLINE
    4      LLINE
    5      LSIDE
    6      RSIDE
    7      XWD  -WC,<LEFT CLEAR  PICTURE> (A  word specifying  a data
                          HAND/EYE LIBRARY                        4-8


           block.  Note that it is not an IOWD; the left half  is the
           negative of the  word count and  the right half  points to
           the location  in the file  of the first  word of  the data
           block.   This word  is  zero if  the data  block  does not
           exist.  See the description of the storage array below for
           the description of these data blocks)
    10     XWD -WC,<LEFT RED PICTURE>
    11     XWD -WC,<LEFT BLUE PICTURE>
    12     XWD -WC,<LEFT GREEN PICTURE>
    13     XWD -WC,<PICTURE TITLE>
    14     XWD -WC,<PICTURE DESCRIPTION>
    15     XWD -WC,<LEFT CAMERA TRANSFORM>
    16     XWD -WC,<LEFT CLEAR CODE TABLE>
    17     XWD -WC,<RIGHT CLEAR PICTURE>
    20     XWD -WC,<RIGHT RED PICTURE>
    21     XWD -WC,<RIGHT BLUE PICTURE>
    22     XWD -WC,<RIGHT GREEN PICTURE>
    23     XWD -WC,<RIGHT CAMERA TRANSFORM>
    24     XWD -WC,<RIGHT CLEAR CODE TABLE>
    25     XWD -XC,<STERO REGISTRATION TABLE>
    26-37  reserved  for other  data block  descriptors which  may be
           added in the  future.  Users may  use this space  for data
           blocks of their  own but it is  subject to use  by library
           programs in the future.  If you have a continuing  use for
           other  data  blocks  see  me  about  adding  them  to  the
           permanent list.
    40-177 reserved  for  user  specified  information  of  any kind.
           These  words  are  not  read  or  written  by  the library
           routines; you have to  have your own disk I/O  routines to
           access them.
    200    beginning of the data blocks

                       DATA BLOCK SPECIFICATION


        The input  and output  routines require as  a parameter  a 25
word integer array which is used to pass information between the user
and the I/O  routines concerning which  data blocks are  available or
desired.  The file format contains room for 25 data blocks.   This is
infinitely  extendable  as  one  of  the  data  blocks  could  be  an
arbitrarily  long array  of descriptors  for more  data  blocks.  The
first fifteen  words of  the 25  word array  are reserved  for system
defined data  blocks.  The  last ten are  available for  user defined
data blocks.  The data block  associated with each word of  the array
is given below:
                          HAND/EYE LIBRARY                        4-9


ARRAY  DATA BLOCK
_____  ____ _____
1      the TV  image through the  clear filter. If  this is  a stereo
       picture  this is  the left  image. If  this is  an  old format
       picture, this is the only data block which is available.
2      the left or only TV image through the red filter
3      the left or only TV image through the blue filter
4      the left or only TV image through the green filter
5      the  picture's  title.   It  is  a  short  string  for titling
       displays,  listings,  etc.    The  string  is  in   ASCII  and
       terminates with a zero character.  It is not, however, in SAIL
       string space.  It must  be copied for use with  SAIL programs,
       using  CVSTR and  CVASC.  On  generating this  data  block for
       output, be sure there is a zero character, or word, at the end
       of  the string.   The count  in the  data block  descriptor is
       words, not characters.  Procedures for processing this and the
       next data block are given later.
6      a description  of the  picture, which  can be  as long  as the
       producer of  the picture  desires.  It  should tell  about the
       picture and associated processing which has been  performed on
       it.  Again, it should end with a zero character.  See comments
       for title, above.
7      the  camera  transform for  the  left or  only  image.   It is
       currently a 8x3 real array containing:
            1:3,1:3    colineation matrix (TV←table)
            4,1:3      lens center in table coordinates
            5,1:2      TV coordinates of point on image plane pierced
                       by the lens axis
            5,3        1
            6:8,1:3    inverse colineation matrix (table←TV)
            7,1:3      pot readings for pan, tilt, focus (camera #1)
            8,1        camera number
            8,2        lens number (camera #1)
            8,3        0
8      code table for left clear image (for compressing data)
9      the right TV image through the clear filter (exists only  if a
       stereo picture)
10     the right TV image  through the red filter for  stereo picture
       only
11     the right TV image through the blue filter for  stereo picture
       only
12     the right TV image through the green filter for stereo picture
       only
13     the  camera transform  for  the right  image  (stereo pictures
       only)
14     right clear code table for stereo pictures only
15     registration table for  stereo pictures (format  unknown since
       stereo pictures do not exist yet)
16-25  reserved for expansion or user defined data blocks
                          HAND/EYE LIBRARY                       4-10


                 INITIALIZING THE PICTURE FILE INPUT



CALL:        NEW←PICINI(CHAN,FILE,EXT,PPN,FAIL,STORAGE);   (SAIL)

DECLARATION: EXTERNAL BOOLEAN PROCEDURE PICINI(INTEGER CHAN,FILE,EXT,
                 PPN; REFERENCE BOOLEAN FAIL; INTEGER ARRAY STORAGE);

        This procedure opens  the disk file FILE.EXT[PPN]  on channel
CHAN.  The  parts of  the file  name are  given to  it in  SIXBIT, as
produced by the SAIL procedure  CVFIL.  If the file cannot  be found,
there is no free core, or there are read errors, FAIL is TRUE on exit
and there is no data.  STORAGE is the 25 (decimal) word array of data
block information.  The procedure clears the array and then fills the
proper entries with the lengths,  in words, of each data  block which
exists in this file.  Unless you are reading a stereo  picture, words
9-25 will always be zero.  If it is an old format picture,  only word
one will be non-zero. If it is a new format black and  white picture,
at most words 1, 5, 6,  7, and 8 will be non-zero. PICINI  also reads
in  the  header  words  described  earlier  and  stores  then  in the
appropriate variables. The value of the procedure is TRUE if it found
a new format file.

                     INPUT OF ENTIRE DATA BLOCKS



CALL:        PICRD(FAIL,STORAGE);                    (SAIL)

DECLARATION: EXTERNAL PROCEDURE PICRD(REFERENCE BOOLEAN FAIL;
                 INTEGER ARRAY STORAGE);

        After calling  PICINI, allocate core  for the  available data
that you want  and put the  address of the  first word of  each block
allocated in the proper entry of STORAGE.  Clear the entries  for any
data blocks which  are available but which  you do not want.   If you
got the core with GETCOR, the IOWD returned plus one can be used (the
left half is ignored).   If you created a SAIL  array, GIOWD(array)+1
or  GLABEL(array[1]) will  produce the  correct entry.   For example,
given a non-zero entry in STORAGE[1] upon return from PICINI,  all of
the below are equivalent to specify where you want the  image through
the clear filter stored:

        STORAGE[1] ← GETCOR(STORAGE[1])+1;
or
        BEGIN INTEGER ARRAY BUF[1:STORAGE[1]];
        STORAGE[1] ← GIOWD(BUF)+1;
                          HAND/EYE LIBRARY                       4-11


or
        BEGIN INTEGER ARRAY BUF[1:STORAGE[1]];
        STORAGE[1] ← GLABEL(BUF[1]);

GIOWD, GETCOR, GLABEL are described elsewhere in the document.


        Each time it  is called, PICRD will  fill the blocks  of core
you gave  it with the  data blocks in  the file.  Data  is transfered
only for data blocks where the entry in STORAGE was non-zero  both on
exit for PICINI and on entry to PICRD.  The procedure does  not check
                                                            ___
your blocks of core to be sure they are big enough.  FAIL is  TRUE on
exit if it was  TRUE on entry (an error  in PICINI) or if  there were
read  errors.   In this  case,  the data  blocks  may or  may  not be
present.

        PICRD may be called  as many times as desired.   For example,
if you  are processing  the image through  each filter  serially, one
array can be created and  its address put in STORAGE[1].   PICRD will
then fill  it with  the picture through  the clear  filter.  Clearing
STORAGE[1] and putting the  array address in STORAGE[2] will  get you
the picture through  the red filter in  the same array the  next time
PICRD is  called.  The same  data block can  also be read  in several
times if desired.  PICRD will not release the channel you gave PICINI
to open the file.  When you  are done with the file it  is considered
good form to release it yourself.

                      INPUT OF FILE DESCRIPTION



CALL:        PICDES(FAIL,STORAGE);                   (SAIL)

DECLARATION: EXTERNAL PROCEDURE PICDES(REFERENCE BOOLEAN FAIL;INTEGER
                 ARRAY STORAGE);

        This entry is  for do-it-yourself fans  who want to  read the
file with their own I/O  routine.  STORAGE is filled with  words 7-37
(octal) of  the data  file, which  contain the  pointers to  the data
blocks in the file, as described in the section on FILE FORMAT above.
FAIL is TRUE on exit if there was an error in PICINI.

                     INPUT OF PARTIAL DATA BLOCKS



CALL:        PICLIN(FIRST,NUM,FAIL,STORAGE);         (SAIL)
                          HAND/EYE LIBRARY                       4-12


DECLARATION: EXTERNAL PROCEDURE PICLIN(INTEGER FIRST, NUM; REFERENCE
                 BOOLEAN FAIL; INTEGER ARRAY STORAGE);

        PICLIN  allows  you to  input  specific lines  of  a picture.
FIRST is the first line  number wanted.  Images will be given  to you
starting with that line and continuing for NUM consecutive lines.  If
¬(FLINE≤FIRST≤LLINE)  then  FIRST←FLINE.  if  NUM≤0  then  NUM←0.  If
NUM+FIRST-1>LLINE then NUM←LLINE-FIRST+1.  STORAGE and FAIL  are used
as in PICRD,  except the lengths of  the storage areas  provided need
only  be NUM*LINLEN  words  long and  only  entries 1-4  and  9-12 of
STORAGE are checked for input.

                           MULTI-FILE INPUT


        Occasionally a  user might  wish to  open several  files with
successive calls on PICINI and then selectively read from them.  This
capability is automatically provided  by these routines if  the array
STORAGE, used by all of them, is declared to be at least 51 (decimal)
words long instead  of 25.  Then, for  each file, call PICINI  with a
different 51 word array.   When calling one of the  other procedures,
STORAGE  should  be  the  array  returned  by  PICINI  when  the file
containing the desired picture was opened and the procedure will then
use that file.  Remember to  release all of these file after  you are
done with them.

        When using this feature, PICDES need not be called.   It will
function properly, although slowly, but the 25 words it normally puts
in STORAGE, are already there,  in words 27-51 of the array  for each
file.  Word 26 contains the channel number the file was open on.  The
user must make sure BIT, LINLEN, FLINE, LLINE, RSIDE, and  LSIDE have
the  correct values  if they  are  not the  same for  all  files; the
procedures do not change them after PICINI has given them to you.  Of
the procedures in this file, only PICLIN uses them.

        If you  call one of  the procedures with  a STORAGE  array of
less than 51 words when several files are open, the one last accessed
will be used.

                              STRING I/O


        As explained above, the title and description are strings but
are not in SAIL string format.  To help novice users, below is a SAIL
procedure  to  convert  from  file  strings  to  SAIL  strings.  This
procedure is not in the library; you have to put it in  your program.
A similar procedure to go  from SAIL strings to file strings  is left
as an exercise for the reader.
                          HAND/EYE LIBRARY                       4-13



COMMENT VALUE IS A STRING, GIVEN ARRAY SIZE S AND THE ARRAY B);

STRING PROCEDURE STRCOM(INTEGER S; INTEGER ARRAY B);
        BEGIN STRING FOO, Y;
        INTEGER I,J;
        FOO ← NULL;
        FOR I←1 STEP 1 UNTIL S DO
                BEGIN
                Y ← CVSTR(B[I]);
                FOR J←1 STEP 1 UNTIL 5 DO IF ¬Y[J FOR 1] THEN
                        RETURN(FOO&Y[1 TO J-1]);
                FOO ← FOO&Y;
                END;
        RETURN(FOO);
        END;
                          HAND/EYE LIBRARY                        5-1


                  ENTER - TV BUFFER FETCH AND STORE
                  _____ _ __ ______ _____ ___ _____

FILE:        ENTER
SIZE:        1066
ENTRY:       GRADNT,GVALUE,INTPNT,GENTER,GETPNT,INTPNT
SUBRS:       GLOBAL, TVIN, MISC, SETANG, ENT
INTERNAL:    TNOISE
ACS:         all

        ENTER is a package of subroutines, used by the edge follower,
to randomly  apply a  gradient operator  to the  TV input,  plus fast
store and access of magnitudes.

        The  operator is  the 3  X 3  gradient operator  developed by
Irwin Sobel and Gary Feldman.  If the nine elements of the image are

                A       B       C

                H       I       D

                G       F       E
then the operator is
        vector G = (A-I)[-1, 1] + (B-I)[0,2] + (C-I)[1, 1]

                   + (D-I)[2, 0] + (E-I)[1,1] + (F-I)[0, -2]

                   + (G-I)[-1, 1] + (H-I)[-2,0]
which can be reduced to

                     vector G = X[1, 0] + Y[0,1]


                                 and


                        |G| = SQRT (X↑2 + Y↑2)


                  where X = C + E + 2D - G - A - 2H


                                 and


                     Y = C + A + 2B - G - E - 2F
                          HAND/EYE LIBRARY                        5-2


        This operator computes X and Y and obtains |G| by means  of a
table lookup (maximum  value is 15 (octal)  if BITS is ≥4.   It calls
SETANG to get a number specifying the direction of the gradient.


CALL:        INTPNT;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE INTPNT;

        INTPNT  is an  initialization  routine which  must  be called
before GENTER, GETPNT, or PUTPNT are called.  It must be called again
each time your program changes cells BITS or TVWID in file GLOBAL, or
when DISKIN is called.   It may be called  before or after the  tv is
read the first time.


CALL:        GRADNT;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE GRADNT;

        GRADNT  selects  gradient  output.   The  magnitude   of  the
gradient  vector at  the specified  point and  the  direction number,
explained under SETANG, will be returned.


CALL:        GVALUE;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE GVALUE;

        GVALUE  selects  intensity  output.   The   actual  digitized
intensity  at the  specified  point will  be returned.   This  is the
default option until GRADNT is called.


CALL:        MAG ← GENTER (X, Y, OUTSID, DIR);       (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE GENTER (INTEGER X,Y;
                 REFERENCE BOOLEAN O;REFERENCE INTEGER D);

        GENTER is given  X and Y and  returns values as  specified by
GRADNT and GVALUE.  The density  or magnitude is returned in  MAG and
the vector character (O for the density) in DIR.

        If the  gradient value  to be returned  is less  than TNOISE,
which is assembled as four, MAG will contain zeros on exit.

        If ST indicates tape input and the point requested is outside
                          HAND/EYE LIBRARY                        5-3


the limits in  core, as specified by  the TV control words,  OUTSID ←
TRUE.  If ST indicates TV  input and STVFL indicated that  the buffer
is empty, it is  filled, with unconverted intensities, STV  is marked
unconverted, and STVFL marked full.

        If the point requested is not currently in the buffer, but is
inside the maximum limits of  the TV image, (TMAX, RSMAX,  etc.), the
TV control words would be adjusted to include the point  requested by
calling  one of  the routines  in file  ENT, STVFL  marked  empty and
GENTER  restarted after  calling INTPNT.   The routine  in ENT  to be
called is specified on entry by OUTSID as follows:

     -1  call ENTERY
     0   call ENTERZ (the angle is assumed to be in DIR)

        If the point requested  is outside the maximum limits  of the
TV image, OUTSID ← TRUE.


CALL:        FOO ← GETPNT(X,Y);                      (SAIL)
             PUTPNT(X,Y,VAL);                        (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE GETPNT (INTEGER X,Y);
             EXTERNAL PROCEDURE PUTPNT (INTEGER X,Y,VAL);

        These procedures  very rapidly get  and store  information in
the TV buffer.  To speed  them up, no checking of the  coordinates is
done to make certain they are in the buffer and the area of the image
read in will not  be changed as with  GENTER; the user must  do these
things himself if it is necessary. All parameters relating to  the TV
buffer  are fixed  by the  initialization procedures,  except TVWORD.
Therefore, several buffers of  the same size may be  accessed without
reinitializing before using each one.   If (x,y) is the point,  in TV
cooordinates,  to  be selected,  X  and Y  are  x-LSIDE  and y-FLINE,
respectively, not the coordinates themselves.  This is easy to  do in
FOR loops.  FOO is the  value of the point (X+LSIDE, Y+FLINE)  in the
buffer.  VAL is  the value to  be stored in  the buffer.  It  will be
truncated to the size specified by BITS when INTPNT was last called.
                          HAND/EYE LIBRARY                        5-4


                    ENT - ADJUST LIMITS OF TV SCAN
                    ___ _ ______ ______ __ __ ____

FILE:        ENT
SIZE:        162
ENTRY:       ENTERZ, ENTERY, ENTINT
SUBRS:       GLOBAL
ACS:         1-3,10-11,13


CALL:        ENTERY (Y);                             (SAIL)

DECLARATION: EXTERNAL PROCEDURE ENTERY (INTEGER Y);

        ENTERY sets the TV control words (FLINE, etc) for a rectangle
eleven  points  high  centered  on the  Y  coordinate  given  it, and
stretching the maximum  width of the TV  image as specified  by RSMAX
and LSMAX. STVFL is set to indicate an empty TV buffer.  This routine
is used by the edge follower for calibration and for the  coarse scan
to find edges.   It does not read  the TV image in.   Normally called
from GENTER or OPER.

        ENTINT is an  internal initialization routine used  by GENTER
and OPER .


CALL:        PUSH 17,DIR                             (FAIL)
             PUSHJ 17,ENTERZ
             JRST INSIDE
             JRST OUTSIDE

        Setup  input for  a square  of width  TVWID (assembled  as 65
decimal),  adjusted  so  that  3/4 of  the  square  in  the direction
specified by DIR is in  front of the point (see SETANG  for direction
specification). The routine skips if the point is outside  the limits
set by TMAX, BMAX, LSMAX, RSMAX and SLIM in file GLOBAL is FALSE.  If
SLIM is TRUE then the actual  limits of the TV image are  used.  This
allows a program to restrict a raster scan using the set limits  to a
limited area for  finding a feature, but  going outside that  area if
necessary while processing the feature.

        Below are two examples of the placement of the squares  of TV
input.

                             SEE FIGURE 3
                          HAND/EYE LIBRARY                        6-1


                   HISTO - FORMS HISTOGRAM OF TVBUF
                   _____ _ _____ _________ __ _____

FILE:        HISTO
SIZE:        125
ENTRIES:     HISTO, HISTL, HYSTAB, GHISTO
SUBRS:       GLOBAL
ACS:         1-4, 6-7


CALL:        PUSHJ 17, HISTO                         (MACRO)
             GHISTO (NOTYPE);                        (SAIL)

DECLARATION: EXTERNAL PROCEDURE GHISTO (BOOLEAN T);

        HISTO finds the  number of samples  at each density  level in
the TV buffer and  types them out in  the order 0-17.  On  exit, they
are stored in HYSTAB to  HYSTAB +17.  The routine halts if  BITS does
not contain 4.

        When called with  HISTO, the histogram  will be typed  out if
HISTL contains a SKIPA, as it does when loaded.  If HISTL  is changed
to a SKIP, the subroutine will exit without typing.

        GHISTO is the SAIL entry.  If NOTYPE is TRUE there will be no
typeout.  If it is FALSE, the histogram will be typed.
                          HAND/EYE LIBRARY                        6-2


                      OPER - HUECKEL'S OPERATOR
                      ____ _ _________ ________

FILE:        OPER
SIZE:        2406
INTERNAL:    ORX, ORY, OCL, OSL, OD, OB (all type REAL)
ENTRY:       OPER, OPINIT
SUBRS:       GLOBAL, ENT, TVIN, MISC
ACS:         0-4

        This program applies a variable sized operator,  developed by
Manfred Hueckel, to  TV images to detect  edges.  While the  speed of
the operators is less than  than of the other operators  described in
this document, they provide  a more complete description of  the edge
and can find edges when excessive noise and lack of  contrast prevent
the other operators from finding the edges.  For a description of the
math behind these operators  see Manfred's paper, "An  Operator Which
Locates Edges in Digitized Pictures".  (AI Memo - 105)


CALL:        OPINIT (C)                              (SAIL)

DECLARATION: EXTERNAL PROCEDURE OPINIT (INTEGER CIRCLE};

        OPINIT initializes the operator for a specified TV  image and
operator size.   It must  be called whenever  the size,  position, or
sample width of the image  changes; the TV buffer is changed;  or the
operator size is changed. CIRCLE is an integer in the range

                            0 < CIRCLE ≤5

indicating  the  operator  size  to  be  used.   The  five  tables of
constants for the operators take up 11000 (octal) words.  The program
can be assembled without the larger operators if they are not needed,
greatly reducing the size of the program. The current version  in the
library  is assembled  with only  the first  two tables.  OPINIT will
return  immediately  if given  any  sizes  other than  1  or  2.  The
operator sizes are as follows:

     CIRCLE   RADIUS*     RANGE**      # OF POINTS USED (octal)
     ______   _______     _______      _ __ ______ ____ _______
                          - +
     1        3.19        3 4          32
     2        4.07        4 5          52
     3        4.67        5 5          69
     4        6.60        7 7          137
     5        7.51        8 8          177
                          HAND/EYE LIBRARY                        6-3


     *        Radius of  the circle approximated  by the  operator in
              points of the TV image.

     **       Extent  of the  operator  in points.  Also  the minimum
              distance from  the edge  of the TV  image at  which the
              operator  will not  extend  outside the  limits  of the
              image. +  and -  refer to the  direction along  the two
              axes.  Therefore, for the operator #1 to be  inside the
              image at point X, Y

                      LSIDE + 3 ≤ X ≤ RSIDE - 4
                      FLINE + 3 ≤ Y ≤ LLINE - 4

        Note that circles  1 and 2 have  a diameter which is  an even
number of resolution  elements.  When these circles  are approximated
by a grid, there  are an even number  of grid points along  both axes
through the operator,  causing the center to  lie outside the  set of
points at  which the  intensities are sampled.   The center  of these
operators are actually at (X+.5, Y+.5), causing a slight shift in the
positive X and Y directions which can be noted in the table above.


CALL:        COH ← OPER (X,Y,ANGLE,FLAG);            (SAIL)

DECLARATION: REAL PROCEDURE OPER(INTEGER X,Y,ANGLE,FLAG);

        OPER  applies  the operator  specified  by OPINIT  to  the TV
image.   The center  is  at (X,Y).   It returns  seven  numbers which
specify an edge,  if one is found,  and give noise  information.  The
edge is specified as follows:

                             SEE FIGURE 6


        If an edge exists in the area covered by the operator:

     ORX,ORY   is the intersection of the edge with a  vector through
               (X,Y) normal to the edge.  Thus (ORX,ORY)  will always
               be a point on the edge inside the area covered  by the
               operator.  The closer  (ORX,ORY) is to (X,Y)  the more
               accurate its  value.  It will  usually be  accurate to
               within 1.5 points anywhere inside the operator.

     OCL,OSL   specifies  the  vector  normal  to  the  edge  through
               ORX,ORY.  It is a unit vector (i.e. OCL↑2 +OSL↑2  = 1)
               and  it always  points  toward the  lighter  side (the
               higher  intensity values).   Therefore, it  is  in the
                          HAND/EYE LIBRARY                        6-4


               direction of the gradient. Again, its  accuracy varies
               in a way that is similar to ORX,ORY.

     OB        The average intensity on the darker side of the edge.

     OD        The difference between the intensities on  either side
               of the  edge. It  will always  be positive  unless the
               average  intensity is  very close  to zero  (<.05), in
               which case it may go negative a small fraction (<.03).
               OB and OD can  become very inaccurate if  the distance
               between  (X,Y)  and (ORX,ORY)  increases.   Wide edges
               make the values much less accurate than noisy ones.

        If there is no edge, the operator will attempt to  divide the
circle so that the noise distribution gives the largest value  of OD,
which should be quite small.  OCL and OSL will take on  random values
and OB will be the average  intensity in the area.  ORX and  ORY will
take on  values which are  often equal to  X and Y  or very  close to
them.  Sometimes, however, ORX and ORY take values much  further from
X,Y than the radius of the operator.

        The seventh number, COH, which is the value of  the operator,
is an indicator of the quality of the edge.  If COH > .98 there is an
edge; if COH < .9 there is not  an edge.  For .9 ≤ COH ≤ .98  an edge
may be present.  Since the  goodness of the edge depends both  on COH
and OD (if OD  is less than the noise  level, you can still  get good
values for COH), Manfred suggests accepting an edge if

             COH + (1 - CONF) x OD↑2 / (DIFF↑2 + OD↑2) >1

where CONF  relates to  COH and  DIFF relates  to OD.   The suggested
ranges are

                           .86 < CONF <.9
                           1.5 < DIFF < 4

        0 ≤ COH  ≤ 1.0 except (1)  when the operator  extends outside
the limits of the TV image, in which case COH = -1.0 and, (2)  if the
operator routines become confused, in which case they terminate early
without setting any  of the variables  listed aboue and  COH=-2.0. If
the operator is inside the TV limits but outside the  current buffer,
a new buffer will be read  in, using the routines in file  ENT.  FLAG
indicates what shape the input area should assume as follows:

     -1  ENTERY
     0   ENTERZ (ANGLE gives the direction)
                          HAND/EYE LIBRARY                        6-5


        FLAG≠0 only if the operator size is 1-3.  The other operators
are wider than the area read in.

        I have experimented running operators of all sizes over edges
of various types, including some so noisy and faint that the gradient
operator probably could not see them.  I propose the following method
of edge detection, which will usually be much faster and, apparently,
more accurate, than the equation given above.

        1.  If COH < .85  or OD < N there  is no edge.  If COH  > .98
and OD > M there  is an edge.  N and  M can be chosen to  reflect the
intensity change expected for the  scene being analyzed.  I used  N =
1, which is  the lowest reasonable  value.  I used M  = 2 but  if you
have an idea of what the intensity change should be, this can  be set
just below that.

        2. For other values, an edge may be present.  One  test which
can be applied here is to reject the edge if

                    (ORX - X)↑2 + (ORY -Y)↑2 ≥ R↑2

where R is the radius of operator in use.

        3.  If great accuracy is not necessary, all edges accepted in
Step 1 can be finished  with now.  My experience has  shown, however,
that,  while the  location  of the  edge is  found  fairly accurately
anywhere inside the  area covered by the  operator, OB and OD  can be
quite unreliable if  (X,Y) is not near  (ORX, ORY).  If  the distance
between them is nearly equal to the radius of the operator,  the edge
may  be found  very accurately,  but OB  and OD  may blow  up, giving
values well outside  of the expected  range (like OB  = 499 and  OD =
813).  In this case the subroutine returns after setting COH=-2.0 and
OB and OD = 0.

        Therefore, for edges which got a maybe rating in test  1, and
sure edges where accuracy is important and (ORX -X)↑2 + (ORY - Y)↑2 >
(R/2)↑2, the  operator should be  applied again, letting  (X,Y) equal
(ORX, ORY) rounded to the nearest integer.  Then apply tests 1  and 2
again. If they fail, there is  no edge.  If they give a  maybe rating
and  OD and  COH are  lower than  or equal  to their  previous value,
reject the edge.   Otherwise apply test  3 again and  continue.  This
process should converge,  usually in two  or less iterations,  if the
right side of the last  equation above is not less than  (R/2)↑2.  If
the points are closer it may oscillate.
                          HAND/EYE LIBRARY                        6-6


                    AVERAG - AVERAGING SUBROUTINE
                    ______ _ _________ __________

FILE:        AVERAG
SIZE:        264
INTERNAL:    NUMBR, TMPBUF
SUBRS:       TVIN, MISC, GLOBAL
ACS:         ALL


CALL:        AVERAG;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE AVERAG;

        AVERAG forms the average over several frames of the specified
area of the TV  input.  On entry the  TV control words should  be set
for TVIN and BITS should contain the sample width of the average.  It
may be any value from 3 through 6.  NUMBR should contain 4, 8,  or 16
to give an average  over 4, 8, or  16 frames.  Any other  number will
give an  8 frame average.   The first image  read is unpacked  into a
temporary buffer in 8 bit bytes and the remainder of the images added
to it.  Then the sums are truncated to the requested number  of bits,
with  rounding, and  put back  in the  TV buffer.   ADJUST  is called
before returning.

        A temporary buffer  must be specified  by putting an  IOWD in
TMPBUF.  If it is not at least twice the length of the TV  buffer the
routine will exit immediately.
                          HAND/EYE LIBRARY                        6-7


     DIFR - ROUTINES FOR DIFFERENCING IMAGES AND PROCESSING THEM
     ____ _ ________ ___ ____________ ______ ___ __________ ____

FILE         DIFR
SIZE:        771
ENTRIES:     DIFER, SUPRES, PRNT, HISTOG
SUBRS:       GLOBAL
ACS:         ALL

        This is a package of procedures for processing differenced TV
images.  They  are in FAIL  and are optimized  for speed.   They work
fastest when the images  were essentially identical except  for noise
(for motion detecting, etc.).


CALL:        DIFER(BUF1, BUF2, THRESH);              (SAIL)

             PUSH 17,BUF1
             PUSH 17,BUF2
             PUSH 17,THRESH
             PUSHJ 17,DIFER                          (FAIL)

DECLARATION: EXTERNAL PROCEDURE DIFER(INTEGER BUF1, BUF2, THRESH);

        This procedure differences two four bit TV images, which must
be of  the same size  (no checking is  done).  The current  values of
FLINE,  LLINE, etc.,  are used  to determine  the dimensions  of both
images.   BUF1 and  BUF2 are  IOWDs (from  GIOWD or  CORGET  in SAIL)
specifying the two buffers.  BUF1 is replaced by the magnitude of the
differences at  each point  of the image.  All differences  less than
THRESH will be set to zero.  THRESH is forced ≥2 by the program.


CALL:        SUPRES(BUFIN, BUFOUT, THRESH);          (SAIL)

             PUSH 17,BUFIN
PUSH 17,BUFOUT
             PUSH 17,THRESH
             PUSHJ 17,SUPRES                         (FAIL)

DECLARATION: EXTERNAL PROCEDURE SUPRES(INTEGER BUFIN,BUFOUT,THRESH);

        This routine applies a  noise suppression operator to  the TV
image in BUFIN and puts  the result in BUFOUT, where the  buffers are
specified by IOWDs as for DIFER.  The TV control words must be set up
for BUFIN.  The  program will change them  for BUFOUT, which  has two
fewer rows and columns.
                          HAND/EYE LIBRARY                        6-8


        A  point  in BUFOUT  is  zero if  the  number  of intensities
greater  than  zero  amoung  the  eight  neighboring  points  of  the
corresponding  point in  BUFIN is  less than  THRESH.   Otherwise the
point has the same value in both buffers.


CALL:        PRNT(BUFR);                             (SAIL)

             PUSH 17,BUFR
             PUSHJ 17,PRNT                           (FAIL)

DECLARATION: EXTERNAL PROCEDURE PRNT(INTEGER BUFR);

        This routine outputs the TV image specified by the  IOWD BUFR
to  the line  printer, using  channel 16.   It is  similar  to PRDUMP
except no table or coordinate numbers are printed.  A row  of periods
is printed across the top and bottom of each strip to show how far it
extends in each dimension.  The numbers 1-7 and letters A-H  are used
to  denote  intensities  1-15 (only  4  bit  samples  allowed), while
intensity zero prints  as a blank.  This  last feature, and  a slight
increase  in  speed, make  it  preferable to  PRDUMP  for differenced
images.


CALL:        HISTOG(BUFR,OUT);                       (SAIL)

             PUSH 17,BUFR
             PUSH 17,[OUT]
             PUSHJ 17,HISTOG                         (FAIL)

DECLARATION: EXTERNAL PROCEDURE HISTOG(INTEGER BUFR; ANY ARRAY OUT);

        This procedure generates the histogram of the 4 bit  TV image
specified by the IOWD  BUFR and the TV  control words and puts  it in
the first sixteen  words of array OUT,  which has better be  at least
that long.  It is similar  to HISTO but much faster for  images which
are mainly zeros.
                          HAND/EYE LIBRARY                        6-9


                   DISP - DISPLAY DIFFERENCED IMAGE
                   ____ _ _______ ___________ _____

FILE:        DISP
ENTRY:       DISPLY
SIZE:        202
SUBRS:       MISC,  QUAM  DISPLAY  ROUTINES,  GLOBAL,   SAIL  RUNTIME
             ROUTINES
ACS:         ALL


CALL:        DISPLY(BUFR,DISBUF,THRESH,DISLEN,FRAME);(SAIL)

DECLARATION: EXTERNAL PROCEDURE DISPLY(INTEGER BUFR;
                 ANY ARRAY DISBUF;INTEGER THRESH, DISLEN,FRAME);

        This procedure generates a fast (and crude) display of the TV
buffer specified  by the  IOWD BUFR  and the  TV control  words.  The
buffer should contain a  differenced image which is mainly  zeros, or
else the display buffer will have to be very large.  A dot is  put on
the display for each nonzero point in the buffer with value ≥ THRESH,
which is  forced by  the program to  be one  or greater.   If several
adjacent point in the same row are nonzero, a horizontal line will be
drawn through them.  DISBUF is an array for use as the display buffer
which is at  least of length DISLEN+2.   FRAME is the piece  of glass
number to be used.  Some version of the QUAM display routines must be
loaded with this file.
                          HAND/EYE LIBRARY                       6-10


                      HUECKEL EDGE-LINE OPERATOR
                      _______ _________ ________

FILE:        OP
SIZE:        3200
ENTRIES:     EJLI,EJINIT
EXTERNAL:    CONF, DIFF
INTERNAL:    B, TM, TP,  N0SQ, S0SQ, COH,  CX, CY, OPX,  OPY, ISEDGE,
             ISLINE,  BCOMP,  WEAK,  NOISY,  NEARED,  OPOOB,  CIRCLE,
             LINWID, OPXM, OPYM, OPXP, OPYP, OPOOB
CALLS:       GLOBAL, SAIL runtime routines, ENT
ACS:         ALL


CALL:        EJINIT(SIZE);                           (SAIL)

             PUSH 17,SIZE
             PUSHJ 17,EJINIT                         (FAIL)

DECLARATION: EXTERNAL PROCEDURE EJINIT(INTEGER SIZE);

        This  procedure  initializes  the  data  structure   for  the
operator.  SIZE is the operator  number (1 and 2 are legal,  the rest
are ignored).  See description of OPER for discussion of  the various
operator sizes.  EJINIT must be call before the first  application of
the operator and,  thereafter, whenever TVWORD, FLINE,  LLINE, RSIDE,
LSIDE  or  BITS are  changed,  or whenever  a  different  operator is
desired.


CALL:        FOUND←EJLI(X,Y,ANGLE,FLAG);             (SAIL)
             PUSH 17,X
             PUSH 17,Y
             PUSH 17,ANGLE
             PUSH 17,FLAG
             PUSHJ 17,EJLI
             JUMPN 1,FOUND                           (FAIL)

DECLARATION: EXTERNAL BOOLEAN PROCEDURE EJLI(INTEGER X,Y,ANGLE,FLAG);

        This procedure applies the  operator at the pont (X,Y)  in TV
coordinates.  The value of the operator is TRUE if there was anything
at  all in  the disc.   One must  set the  decision  variables before
calling.  CONF  should  be  set  to  the  desired  confidence.  It is
recommended that  .85<CONF<.99.  DIFF  should be  set to  the minimum
signal strength allowable.   Both DIFF and  CONF must be  declared in
your program as INTERNAL REAL and initialized by your  program before
using.  The signal strength is returned in S0SQ and is the sum of the
                          HAND/EYE LIBRARY                       6-11


squares of the components of the fourier expansion.  There is a vague
relatin between  the signal  strength and the  square of  the minimum
brightness step size.   The recommended range is  2.0<DIFF<10.0.  The
actual confidence is returned  in COH and is  S0SQ/(S0SQ+N0SQ).  N0SQ
is a measure of the amount  of signal that is not an  ideal edge-line
element.

        The boolean WEAK will be TRUE if the operator  failed because
there was  very little  action in the  disc.  NOISY  will be  TRUE if
there was plenty of  action, but it did  not look much like  an ideal
edge-line element.  OPOOB will be  TRUE if X,Y was outside  the field
of view of the TV or the operator was prevented from moving its input
rectangle.  FLAG and ANGLE are used to move the rectangle,  using the
mechanism described under OPER.

        The disc  is partitioned upon  success into three  regions of
brightness, B, B+TM, and B+TM+TP, respectively.  It is partitioned by
two straight lines whose equations are  CX*X+CY*Y=CX*OPXM+CY*OPYM and
CX*X+CY*Y=CX*OPXP+CY*OPYP respectively.  CX and CY are  the direction
cosines  of  the  line  and  (OPXM,OPYM)  and  (OPXP,OPYP)   are  the
coordinates of the closest points  on the lines to the center  of the
operator.

        There is a variable, R,  that is the weighted average  of the
distances to each of the lines.  If the disc is placed over  an ideal
edge element, R will be the  distance from the center of the  disc to
the center of the edge  OPX,OPY are the coordinates of the  center of
the  edge-line  element.  The  boolean  ISLINE will  be  TRUE  if the
element looks more like a line than an edge, and ISEDGE will  be TRUE
if it looks  more like an  edge than a  line.  Ofter neither  will be
TRUE.  The boolean NEARED will  be TRUE if the edge-line  element was
too close to the edge of the disc to be confident of the position and
brightness information.

        BCOMP is TRUE if  the internal computation went  complex.  In
this case,  the brightness is  set to the  average brightness  of the
picture  inside the  disc, but  R, OPX,  OPY, CX,,  and CY  are still
meaningful.  In this case, the data in the disc was too  confusing to
have a meaningful  fit as an ideal  edge-line element, but  often the
operator can  be moved either  to (OPX,OPY) or  down the line  in the
direction  specified by  CX  and CY  are will  then  yield meaningful
results.

        If the element in the  disc is definitely a line,  the number
LINWID is  returned as the  width of the  line.  It is  equivalent to
SQRT((OPXP-OPXM)↑2+(OPYP-OPYM)↑2).
                          HAND/EYE LIBRARY                       6-12


        The disc radius in  floating point is in CIRCLE  after EJINIT
has been called.

        In using  the operator, remember  that many things  look like
lines.   For instance,  two parallel  nearby edges  may very  well be
called a line.
                          HAND/EYE LIBRARY                        7-1


                 PICWR - WRITE A PICTURE ON THE DISK
                 _____ _ _____ _ _______ __ ___ ____

FILE         PICWR
SIZE:        170
SUBRS:       SAIL RUNTIME ROUTINES, GLOBAL
ENTRIES:     PICWR, PICWI, PICOUT, PICCLS
ACS:         ALL


CALL:        PICWR(CHAN,FILE,EXT,PPN,FAIL,STORAGE)   (SAIL)

DECLARATION: EXTERNAL PROCEDURE PICWR(INTEGER CHAN, FILE, EXT, PPN;
                 REFERENCE BOOLEAN FAIL; INTEGER ARRAY STORAGE);

        This procedure writes out a picture onto a disk file,  in the
new picture format  (see PICRD for a  description of the  file format
and the storage array).  CHAN is the channel number for  output.  The
picture is  put on file  FILE.EXT[PPN], where the  parts of  the file
descriptor are sixbit words as produced by CVFIL.  STORAGE is  the 25
word  array specifying  the data  blocks to  be written.   Each entry
contains  zero, if  that data  block does  not exist,  or  XWD -<word
count>, <address of first word of array or block of core containing a
data block>. This is an IOWD+1.  FAIL is TRUE on exit if there was an
error of any kind, in which case the picture was not written out.


WRITING PICTURE FILES IN SECTIONS

        The  above procedure  writes out  an entire  picture  file at
once,  which  is  the   easiest  method  for  the  user.    For  some
applications  one does  not  want to  have  to allocate  at  one time
sufficient buffers for all data blocks to be written out.   The three
procedures below allow the outputting of one or more data blocks at a
time and, thus, the ability to reuse the storage space.  PICWR simply
calls these routines in sequence.  The ability to write out more than
one file at  once is not provided.   Users desiring this  feature are
encouraged to write the code themselves.


CALL:        PICWI(CHAN,FILE,EXT,PPN,FAIL);          (SAIL)

DECLARATION: EXTERNAL PROCEDURE PICWI(INTEGER CHAN, FILE, EXT, PPN;
                 REFERENCE BOOLEAN FAIL);

        This procedure initializes the outputting of a  picture.  The
arguments, and  errors, are the  same as for  PICWR except  the array
STORAGE is not provided.  No data is written out by this routine.
                          HAND/EYE LIBRARY                        7-2


CALL:        PICOUT(FAIL, STORAGE);                  (SAIL)

DECLARATION: EXTERNAL PROCEDURE PICOUT(REFERENCE BOOLEAN FAIL;
                 INTEGER ARRAY STORAGE);

        Each  call of  PICOUT outputs  the data  blocks  specified by
STORAGE, which is  set up as explained  for PICWR.  FAIL is  FALSE if
there were no errors.  FAIL is negative if PICWI failed and  there is
no file open.  FAIL is positive if one or more of the data  blocks in
this call were written out by a previous call.  The value of  FAIL is
the number of such data  blocks.  They will not be written  out again
(for example, you can only write out the left clear TV image once per
file) but all  other data blocks will  be written out.   If duplicate
blocks  were  allowed,  only  the  one  written  out  last  would  be
accessible, since the header block  only has one entry for  each data
block, and the earlier copies would be taking up space in the file.


CALL:        PICCLS;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE PICCLS;

        This  procedure finishes  writing  out the  last  data block,
writes out  the header  block, (using  the values  of the  TV control
words as of the execution of PICWI), and releases the file.
                          HAND/EYE LIBRARY                        7-3


              PICSPL - SPOOL IMAGES FOR THE LINE PRINTER
              ______ _ _____ ______ ___ ___ ____ _______

FILE:        PICSPL
ENTRIES:     PICSPL
SIZE:        600
SUBRS:       GLOBAL
ACS:         1-7, 16


CALL:        PICSPL(FLAG, TITLE);                    (SAIL)

DECLARATION: EXTERNAL PROCEDURE PICSPL(BOOLEAN FLAG; STRING TITLE);

        PICSPL outputs  the TV  buffer to  the spooler  for printing.
Temporary  listing files  are  created on  your disk  area;  they are
deleted by  the spooler.   Channel 16 is  used for  all I/O.   If the
image is too wide to fit on one page, it will be printed in sections,
which can be placed side  by side to get the complete  picture.  Each
section starts at the top  of a new page and ignores  page boundaries
thereafter.  TITLE is a heading, which can be the null  string, which
will be printed at the top of each section.  One carriage  return and
line feed  is provided by  this routine between  the heading  and the
picture.

        If  FLAG is  FALSE,  the image  is printed  with  sixteen (?)
levels of grey scale,  obtained by overprinting lines.  If  the image
has more than four bits per sample, the high order bits will be used.
Three bit  pictures will  be shifted  to use  the darkest  levels for
better contrast.

        If  FLAG  is TRUE,  the  intensities at  each  point  will be
printed, using letter codes for intensities above 9.   The conversion
table is printed  after the last section.   The Y coordinates  of the
image are printed, in octal,  every eight lines on both the  left and
right margins  of each  section.  The X  coordinates are  printed, in
octal, every eight columns across the top and bottom of each section.
The column under the first  digit of each number corresponds  to that
coordinate.
                          HAND/EYE LIBRARY                        7-4


                       PORTR - PORTRAIT PRINTER
                       _____ _ ________ _______

FILE:        PORTR
SIZE:        122
INTERNAL:    PRTBUF
SUBRS:       GLOBAL, PICSPL
ACS:         1-7, 16


CALL:        PORTR(TITLE);                           (SAIL)

DECLARATION: EXTERNAL PROCEDURE PORTR(STRING TITLE);

        This is IRWIN SOBEL'S portrait program.  The distance between
characters  on the  line printer  is less  than the  distance between
lines.  Therefore, pictures printed by PICSPL appear stretched in the
Y  direction.   Given  an image  specified  by  TVWORD,  this routine
creates a new image, specified by an IOWD which the user must  put in
PRTBUF before  calling, which  has its aspect  ratio adjusted  so the
picture will  print properly.   This feature  is necessary  for doing
useful things like printing  pictures of your friends, who  might not
appreciate being tall and thin.   PICSPL is then called to  spool the
corrected image,  using grey  scale output.   The array  specified by
PRTBUF should be the same size as the one specified by TVWORD. It may
be  the same  array if  the original  image is  not needed  any more.
TITLE is for PICSPL.
                          HAND/EYE LIBRARY                        7-5


                VIDEO - TV IMAGE TO VIDEO SYNTHESIZER
                _____ _ __ _____ __ _____ ___________

FILE:        VIDEO
SIZE:        SAIL PROCEDURE
ENTRIES:     CANMAIL, VIDEO, JOBOK, DDVID, OVERL
SUBRS:       GLOBAL, SAIL RUNTIME ROUTINES
ACS:         ALL


DDVID FOR BEGINNERS

        DDVID.DMP[1,PDQ] is a program which generates  pictures using
the video synthesizer.  Since it is a large program, it is not run as
a part  of hand/eye  jobs, but  as a  seperate job.   It can  be used
either  by typing  commands  directly at  it, or  by  sending command
strings to it through the system's mail mechanism.  The procedures in
this  file  are provided  to  perform the  linkage  through  the mail
mechanism.

        Before starting a copy of DDVID, check WHO to determine  if a
copy already exists and, if so, if it is in use.  Otherwise  you will
erase someone's picture, which can lead to unnecessary violence.  You
may start DDVID and then detach  it but, due to system bugs,  it will
occasionally die.  It  is best to find  an unused console and  run it
there (even a teletype will  do). DDVID puts out its picture  on data
disk channel 47,  which can be ORed  into your channel, or  viewed in
place of your channel.  The program also requires six  other channels
to generate the picture.  It will try to get unused channels from the
system to use,  but will fail if  the system is heavily  loaded.  You
will get  a message from  DDVID when  you start it  if it  cannot get
enough channels.  You really do not want to run it when the system is
that loaded anyway.  Once you have the channels, DDVID will  not give
them back to the system, unless you restart it.  This is a sneaky way
of reducing the number of job running.


CHECKING DDVID STATUS

        The following  procedures are internal  routines used  by the
other procedures in  the file but  they may also  be of use  by users
since the main procedures in this file type error messages but do not
inform the calling program of the nature of the error.


CALL:        INT←JOBOK(JOBNO);                       (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE JOBOK(REFERENCE INTEGER
                 JOBNO);
                          HAND/EYE LIBRARY                        7-6


        This procedure checks the status of DDIVD jobs and returns an
integer decoded as follows:

     0   no copies of DDVID are running

     1   more than  one copy  of DDVID  is running  and there  is not
         exactly one copy with your PPN.

     2   there is only one copy of DDVID running, or only one running
         under your PPN.  In this case, JOBNO contains, on  exit, the
         job number of  the copy of DDVID  which will be used  by the
         other procedures in this file.  They all call JOBOK and fail
         unless it returns 2.


CALL:        OK←CANMAIL(JOBNO);                      (SAIL)

DECLARATION: EXTERNAL BOOLEAN PROCEDURE CANMAIL(INTEGER JOBNO);

        Given JOBNO, as returned by procedure JOBOK when its value is
2, this procedure is TRUE if the job is currently accepting mail.  If
it  is FALSE,  the job  already  has mail  waiting which  it  has not
accepted.  Either you are shoving  strings at it too fast, or  it has
died.


DDVID COMMANDS

        Commands  to DDVID  consist of  single  characters, sometimes
followed  by one  or more  arguments, seperated  by  commas.  Command
strings sent by the procedures below consist of a series of commands,
seperated by semicolons.  There  are many commands available  (type ?
at DDVID itsself for a list).  Here are some of the more  useful ones
for our applications.

     E     erases all previous pictures

     →n    attenuates the picture by  shifting each sample n  bits to
           the right.  Pictures to be overlayed with graphics must be
           shifted at least one bit as the overlay is put out  as the
           high order bit.   Pictures with less  than 6 bits  are put
           out on the highest (brightest) channels.

     ↔n    expand the picture n times, where n=1, 2, or 4. One is the
           normal expansion; four is usually too large to fit  on the
           screen.
                          HAND/EYE LIBRARY                        7-7


     Xn,m  positions  the  upper  left  corner  of  the   picture  at
           coordinates  n,m using  the TV  coordinate system  (0,0 is
           upper left corner of screen, with X to right and  Y down).
           You can position the picture with this command or the next
           two.

     Fn,m  divide the screen into n x m pictures, with n  pictures on
           each row and m rows.  F1,1 is the normal case,  giving one
           picture in the middle of the screen.

     Li    this picture is to be displayed in the ith position, where
           i=0 is the upper  left and numbering increases  across and
           then down.

        A sample command line, for use with overlaying, might be

        E;→2;↔2;F1,1;L0;


SENDING PICTURES TO DDVID

        As mentioned  above, commands are  sent to DDVID  through the
system mail mechanism.  Pictures  to be displayed are  transmitted by
detaching  your upper  segment, creating  and linking  to a  new one,
copying your TV image, as specified by TVWORD, into the  new segment,
detaching the new segment,  reattaching the old segment,  and telling
DDVID the segment name of the new segment so it can attach to  it and
get the picture.  If anything goes wrong, you may have either segment
attached.  If this  sound like a horrible  way to do things,  you are
right but it is the best  we have.  If you are still  interested, the
procedures below are available to link to DDVID.

        If only one  copy of DDVID is  running, it will be  used.  If
there are several copies of DDVID but only one running under the same
PPN as the calling job, that copy will be used.  In all  other cases,
an error message will be typed.  If an error is detected, or DDVID is
not accepting pictures,  the procedures return FALSE;  otherwise they
are TRUE.  The procedures do not wait for DDVID to put out  the image
before returning.


CALL:        TST←DDVID(COMSTR);                      (SAIL)

DECLARATION: EXTERNAL BOOLEAN PROCEDURE DDVID(STRING CONSTR);

        The command string  COMSTR is send  to DDVID, along  with the
picture specified by TVWORD  and the TV control words.   The commands
                          HAND/EYE LIBRARY                        7-8


which can be sent include, but are not restricted to, the ones listed
above.  This  routine must be  used to send  picture which are  to be
overlayed with graphics.  For users wanting only the  picture output,
and not  wanting to  bother with the  command strings,  the following
procedure is provided.


CALL:        OK ← VIDEO(EXP,X,Y);                    (SAIL)

DECLARATION: EXTERNAL BOOLEAN PROCEDURE VIDEO(INTEGER EXP,X,Y);

        The TV image specified by TVWORD is sent to DDVID.  EXP  is a
small integer specifying the power of two by which the picture should
be blown up  for displaying.  The  smallest picture (EXP=1)  is twice
normal  size. EXP=2  is the  other  good size.  X and  Y  specify the
coordinates of the upper left  corner of the image in  TV coordinates
(upper left corner of screen is 0,0).


OVERLAYING GRAPHICS

        It is possible  to overlay a  display, generated by  the Quam
display routines, on top of a DDVID picture.  To get proper alignment
you  must output  the  picture using  the DDVID  procedure,  with the
position specified by  the F and L  commands.  The picture  should be
displayed before  attempting the overlay.   Most of the  arguments to
the overlay procedure are repeating command arguments sent  to DDVID.
The display is not sent to DDVID, it is done by the  display routines
and, therefore, must also  be told the position and  size information
so the two outputs will match.


CALL:        OVERL(DPYBUF,N,M,L,EXP,CHAN);           (SAIL)

DECLARATION: EXTERNAL PROCEDURE OVERL(INTEGER ARRAY DPYBUF;
                 INTEGER N, M, L, EXP; BOOLEAN CHAN);

        This  procedure overlays  a  DDVID picture  with  the display
contained in display buffer DPYBUF.  N and M are the arguments of the
F command sent with the picture being overlayed, L is the argument of
the L  command, and EXP  is the argument  of the ↔  command (=1  if ↔
command was  not sent).   If CHAN  is TRUE,  the buffer  is overlayed
using your  data disk channel;  otherwise it goes  on one  of DDVID's
channels.
                          HAND/EYE LIBRARY                        8-1


                      MISCELLANEOUS SUBROUTINES
                      _____________ ___________

FILE:        MISC
SIZE:        144
SUBRS:       GLOBAL
ENTRIES:     GXCT,  LABEL,  GIOWD,  BUTTON,  ADJUST,  SPWON,  SPWOFF,
             ADCHG, RDCHG, FADCHG, FRDCHG
ACS:         1-3, 16

        This   file   contains   various   small,   frequently   used
subroutines.


CALL:        ADJUST;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE ADJUST;

        ADJUST uses BITS to change TVOUT and LINLEN.  This subroutine
must be called by any  routine written by the user which  changes the
number of  bits per sample  in the TV  buffer or the  output routines
will not work properly.


CALL:        PUSHJ 17, BUTTON                        (MACRO)
             FOO ← BUTTON;                           (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE BUTTON;

        BUTTON - In many programs it is desired to move the rectangle
around the TV picture.  For this and other applications there exist a
set of  eight buttons  (known as SPACEWAR  buttons for  reasons which
shall not be divulged here) in two boxes near the TV Camera.   If any
of  the buttons  are depressed  when this  subroutine is  called, the
appropriate bit in accumulator 1 is one when the routine  exits.  The
buttons are read into the right  eight bits of the word as  marked on
the side of the buttons; the remainder of the word is cleared.

        The following  subroutines are for  use with  SAIL procedures
only:


CALL:        FOO ← GIOWD (A);                        (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE GIOWD (ANY ARRAY A);

        A is  a one-dimensional  SAIL array  identifier.  An  IOWD is
returned in FOO specifying the start and length of the array.
                          HAND/EYE LIBRARY                        8-2




CALL:        FOO ← GLABEL ← GLABEL(VAR);             (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE GLABEL (REFERENCE ANY V);

        The address of VAR is returned in FOO.


CALL:        FOO ← GXCT (INST,ARGL);                 (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE GXCT (ANY I,A);

        ARG is placed in AC1 and INST is executed.  FOO is the result
in AC1.


CALL:        SPWOFF;                                 (SAIL)

DECLARATION: EXTERNAL PROCEDURE SPWOFF;

        Turns off spacewar mode.


CALL:        SPWON(TICK,ADDR);                       (SAIL)

DECLARATION: EXTERNAL PROCEDURE SPWON(INTEGER TICK;
                 REFERENCE INTEGER ADDR);

        Turns on spacewar mode by executing SPCWAR TICK,ADDR.


CALL:        ADCHG(X,Y,PROC);                        (SAIL)

             PUSH 17,X
             PUSH 17,Y
             PUSH 17,[PROC]
             PUSHJ 17,ADCHG                          (FAIL)

DECLARATION: EXTERNAL PROCEDURE ADCHG(INTEGER X,Y;PROCEDURE PROC);

        X and  Y are  assumed to be  absolute TV  coordinates.  ADCHG
converts them to III  display coordinates and transfers  to procedure
PROC, which is normally AVECT, AIVECT, or APOINT in the  Quam display
package.  Any other  procedure can be used  which expects X and  Y as
its last two arguments.  ADCHG converts them in the stack and flushed
the procedure address.  Then  it JRSTs to the procedure,  leaving the
return on the stack.
                          HAND/EYE LIBRARY                        8-3




CALL:        RDCHG(X,Y,PROC);                        (SAIL)

        RDCHG is  identical to  ADCHG except  it expects  relative TV
coordinates and normally calls RIVECT, RVECT, or RPOINT.

        There  also  exist  routines  FADCHG  and  FRDCHG  which  are
identical in use to ADCHG and RDCHG except they take X and Y are REAL
variables.  There produce much more accurate displays if X and  Y can
take real values.

        The following subroutines are for internal use only:


LOCKON

LOCKOF
                          HAND/EYE LIBRARY                        8-4


                     LOOKUP - SYMBOL TABLE SEARCH
                     ______ _ ______ _____ ______

FILE:        LOOKUP
SIZE:        24
ACS:         1-3, 16


CALL:        PUSHJ 17, LOOKP                         (MACRO)

        LOOKP is called with the  RADIX50 code for a symbol  in AC16.
It will skip one instruction  when it returns if the symbol  given to
it exists  in the symbol  table as a  global and leaves  the symbol's
value in AC16.
                          HAND/EYE LIBRARY                        8-5


                      POT - POT READING ROUTINE
                      ___ _ ___ _______ _______

FILE:        POT
SIZE:        145
ENTRIES:     POTABS, POTREL
INTERNAL:    POTS
ACS:         1-10


CALL:        VAL ← POTABS (CHAN, FLAG);              (SAIL)
             VAL ← POTREL (CHAN, FLAG);

DECLARATION: EXTERNAL INTEGER PROCEDURE POTABS (INTEGER CHAN;
                 REFERENCE INTEGER FLAG);
             EXTERNAL INTEGER PROCEDURE POTREL (INTEGER CHAN;
                 REFERENCE INTEGER FLAG);

        POTABS and POTREL read the pots attached to A-D  channels 12-
15.  CHAN is a  number in the range 1  thru 4 to indicate the  pot on
channel  12  through 15  and  the  pot reading  for  that  channel is
returned.  Cells  POTS and POTS  + 1 contain  all four  raw readings,
twelve bits per channel.  If CHAN is zero, the value of the procedure
for all four channels  is put in cells POTS  through POTS + 3  and no
value returned.

        POTABS gives the absolute  pot reading, which will be  in the
range -2048  to about 2044  (decimal).  Be warned  that the  pots are
noisy in the last two bits, are not linear, and not repeatable.

        POTREL gives the pot reading relative to the last reading for
that channel.   If FLAG  is ≠0 on  entry, the  last reading  for that
channel, or all four if CHAN = 0, will be set to the current reading.
Zero will be the value of the procedure in this case.

        On exit, FLAG is set as follows:

     FLAG   MEANS
     ____   _____
     0      OK
     1      Illegal channel number (<0 or >4)
     -1     Could not initialize A-D on 1000 consecutive tries.
     -2     Data missed from 136 on 1000 consecutive tries.

HINT FOR POT USERS     [Don't get caught!]

        Some library  routines using the  pots read them  in relative
mode  and scale  the  result so  that a  complete  turn of  a  pot is
slightly more  than the  range of the  variable being  changed.  This
                          HAND/EYE LIBRARY                        8-6


means that it is possible, in fact easy, to get the pot in a position
where turning it to its stop in the proper direction does  not change
the variable  as far in  that direction as  you want.  In  this case,
rotate the pot  as far as  it will go the  other way.  This  puts the
variable at one of its limits and then if you move the pot  the other
way, you have the entire range at your disposal.
                          HAND/EYE LIBRARY                        8-7


                 GLBGET - READ GLOBAL DATA STRUCTURE
                 ______ _ ____ ______ ____ _________



FILE:        GLBGET
SIZE:        SAIL PROGRAM
INTERNAL:    REQUIREs PREAMB.SAI
ACS: ALL


CALL:        BLOBS←GLBGET;                           (SAIL)

DECLARATION: EXTERNAL SET PROCEDURE GLBGET;

        This procedure reads in the global data  structure proceduced
by the curve fitter from disk files.  See EDGCUR.LST[SYS,HE]  for the
edge  follower  commands  which  dump  the  data  structure  and  for
descriptions of the data structure and the file format.

        The program requests a file name and then reads in  the file,
regenerating the data  structure in the  global model.  It  then asks
for another file  name.  As many files  as desired may be  entered at
once.  A new object  item is created for  each object in each  of the
files.  When input is terminated by giving the procedure a  null file
name, it returns the object items as a set.
                          HAND/EYE LIBRARY                        8-8


       INTERP - INTERRUPT ROUTINE (as used by hand/eye system)
       ______ _ _________ _______ ___ ____ __ ________ _______

FILE:        INTERP
SIZE:        60
ENTRIES:     INTINT, INTWAIT
INTERNAL:    DISABLE
ACS:         1

        INTERP allows  SAIL programs  to use the  TTY, PTY,  and MAIL
interrupts in the system.


CALL:        INTINT(TTY,PTY,MAIL);                   (SAIL)

DECLARATION: EXTERNAL PROCEDURE INTINT(BOOLEAN TTY,PTY,MAIL);

        This  routine initializes  the interrupts  and masks  them so
they  will not  break.  All  interrupts pending  are  lost.  Previous
interrupt  addresses, if  any,  in JOBAPR  are  destroyed.  Arguments
which are TRUE enable interrupts as follows:

          TTY      teletype input

          PTY      pseudo-teletype input

          MAIL     mail waiting

        If DISABL,  assembled as  FALSE, is set  TRUE when  INTINT is
called, the interrupt feature is disabled and INTWAIT will sleep four
ticks and return whenever called.  This is mainly for debugging.


CALL:        INTWAIT;                                (SAIL)

DECLARATION: EXTERNAL PROCEDURE INTWAIT;

        When INTWAIT  is called, the  interrupts requested  by INTINT
are  unmasked  and  the  program  goes  into  interrupt   wait.   Any
interrupts which  are pending (the  condition occured since  the last
call of INTWAIT or INTINT but was masked out) will cause an immediate
interrupt.  Whenever  an interrupt occurs  it will be  dismissed, the
masks  will be  set again,  and the  procedure returns.   The calling
program must  then check  to determine  what condition(s)  caused the
interrupt by interrogating the system or checking JOBCNI.

        The error message "INTERRUPT ROUTINE CONFUSED" means:
                          HAND/EYE LIBRARY                        8-9


1.  You  just did  ↑C  and S  to  restart your  program.   Ignore the
    message.

2.  You tried to continue your  program from DDT when it has  been in
    interrupt wait.  You should have started it at INTWAIT or  it may
    even be fatal.

3.  The timesharing system  has interrupted but no  condition enabled
    for is present.  Shoot a systems programmer.

4.  You tried to  run another program  which the current  program was
    waiting for an interrupt.  You will win if you try it again.
                          HAND/EYE LIBRARY                       8-10


                    TELL - WHO HAS YOUR I/O DEVICE
                    ____ _ ___ ___ ____ ___ ______

FILE:        TELL
SIZE:        101
ACS:         1-7


CALL:        TELL(DEVICE);                           (SAIL)

             PUSH 17,DEVICE
             PUSHJ 17,TELL                           (MACRO)

DECLARATION: EXTERNAL PROCEDURE TELL(INTEGER DEVICE);

        DEVICE  is  the  name  of  an  I/O  device  in  SIXBIT.  This
procedure will type out a message of the form

                  device INITED BY JOB n, PPN= x,xxx

where 'device' is the  device name you gave  it.  If there is  no job
number or PPN, the device was not initialized or assigned at the time
the procedure checked the system's device tables.
                          HAND/EYE LIBRARY                       8-11


                      SETANG - ANGLE CONVERSION
                      ______ _ _____ __________

FILE:        SETANG
SIZE:        206
ACS:         1, 2, 12, 13


CALL:        ANGLE ← SETANG(DX, DY);                 (SAIL)

DECLARATION: EXTERNAL INTEGER PROCEDURE SETANG(INTEGER DX, DY);

        DX and DY  are the (signed) X  and Y components of  a vector.
SETANG returns  the angle number  for that vector,  used in  OPER and
ENTER. |DX| and |DY| must be less than 16.  The number is interpreted
as follows (TV coordinates):
                4
            5      3
        6       o       2   X→
            7      1
                0

                Y
                ↓